﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using HalconDotNet;
using System.IO;
using System.Drawing.Imaging;
using CustomControls;
using System.Diagnostics;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using SimpleCADControl.GeoObjects;
using DCP;
using ParameterWriter;
using System.Runtime.InteropServices;
using DigitalRune.Windows.Docking;
using System.Threading.Tasks;
//using Excel = Microsoft.Office.Interop.Excel;




namespace cellAnalysis
{
    delegate void runAlgo(Object pars);
    delegate void AddSourceControlDelegate(TImage img);
    delegate void AddSourceControlDelegate2(TImage img, Color color);
    delegate void ShowCellStatisticsInGridDelegate(List<cellData> cells);
    delegate void TimeToTextboxDelegate(Stopwatch timer);
    delegate void TimeToTextboxStapelDelegate(Stopwatch timer);
    delegate void ViewInDataGridDelegate(DataGridViewRow row);



    public partial class cellAnalysisForm : DigitalRune.Windows.Docking.DockableForm
    {
        #region COM-Interfaces

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool FlashWindowEx(ref FLASHWINFO pwfi);

        [StructLayout(LayoutKind.Sequential)]
        public struct FLASHWINFO
        {
            public UInt32 cbSize;
            public IntPtr hwnd;
            public UInt32 dwFlags;
            public UInt32 uCount;
            public UInt32 dwTimeout;
        }

        public const UInt32 FLASHW_ALL = 3;


        [DllImport("user32.dll")]
        static extern IntPtr CreateIconFromResource(byte[] presbits, uint dwResSize, bool fIcon, uint dwVer);
        [DllImport("user32.dll")]
        static extern short GetAsyncKeyState(System.Windows.Forms.Keys vKey);
        #endregion
        Thread thread;
        String TemplateFileName;
        List<SimpleCADControl.Vector2D[]> contourList = new List<SimpleCADControl.Vector2D[]>();
        List<SimpleCADControl.Vector2D[]> coresContourList = new List<SimpleCADControl.Vector2D[]>();
        Dictionary<ImageControl.ImagePreviewBox, String> tempProjectName = new Dictionary<ImageControl.ImagePreviewBox, string>();
        public object lockvar = "";
        private List<GeoObject> GeoObjects_Saved;
        private Cursor busyCursor;
        private ParameterWriter.ParameterWriter Parameters;
        private bool inProcess = false;
        Stopwatch timer = new Stopwatch();
        private List<cellData> cells = new List<cellData>();
        List<cellData> cells_SAV;
        List<cellData> newCellList = new List<cellData>();
        private List<TImage> TemplateList = new List<TImage>();
        private List<TImage> TemplateCellSegList = new List<TImage>();
        private TImage SourceImage;
        private HObject mainImg;
        private HWindow window;
        private Dictionary<Polygon, cellData> cellPolyCollection = new Dictionary<Polygon, cellData>();
        private Dictionary<DataGridViewRow, Polygon> cellDataPolyCollection = new Dictionary<DataGridViewRow, SimpleCADControl.GeoObjects.Polygon>();
        private List<Thread> threadPool = new List<Thread>();
        private bool breakLoop = false;
        public cellAnalysisForm()
        {
            InitializeComponent();
            window = hWindowControl1.HalconWindow;
            statusBar_Steps.TbManager.SetProgressState(Microsoft.WindowsAPICodePack.Taskbar.TaskbarProgressBarState.NoProgress);
            mainWindow.ObjectClicked += new EventHandler<SimpleCADControl.GeoObjectEventArgs>(mainWindow_ObjectClicked);
            mainWindow.ObjectDeleted += new EventHandler<SimpleCADControl.GeoObjectEventArgs>(mainWindow_ObjectDeleted);
            mainWindow.Undone += new EventHandler<EventArgs>(mainWindow_Undone);

            //Parameterdatei laden falls vorhanden
            Parameters = new ParameterWriter.ParameterWriter();

            IntPtr hCursor;
            try
            {
                byte[] resource = Properties.Resources.CURSOR;
                hCursor = CreateIconFromResource(resource, (uint)resource.Length, false, 0x00030000);
                busyCursor = Cursors.WaitCursor;
            }
            catch { }

            comboBox_Color.DataSource = Enum.GetValues(typeof(ImagePreprocessing.ImagePreprocessing._Color));

            toolTip_CellClusterSplittingA.SetToolTip(this.checkBox_cellclustersplittingA, "Use Cluster Splitting A in general for splitting cells of type 'L929' or similar cell types");
            toolTip_CellClusterSplittingB.SetToolTip(this.checkBox_cellclustersplittingB, "Use Cluster Splitting B in general for splitting cells of type 'MC3T3' or similar cell types");
            toolTip_FastClusterSplitting.SetToolTip(this.checkBox_contextBasedSeparation, "The fast cluster separation splitts objects at narrow areas. It can be combined with Cell Cluster Splitting A or B to reduce the calculation time.");
        }

        void mainWindow_Undone(object sender, EventArgs e)
        {
            this.Invoke((MethodInvoker)delegate()
            {
                toolStripButton_SyncHalObjWithGeoObj_Click(this, new EventArgs());
            });
            update();
        }

        public void setDefaultVarAlgo()
        {
            inProcess = false;
            this.Invoke((MethodInvoker)delegate()
            {
                this.Cursor = Cursors.Default;
            });
        }

        protected override void OnShown(EventArgs e)
        {
            this.DockState = DigitalRune.Windows.Docking.DockState.Document;
            base.OnShown(e);
        }

        void SyncParameterClassWithGUIParameters()
        {
            //-----------------------------------------------------------------------------------------
            //Allg. Einstellungen
            //-----------------------------------------------------------------------------------------
            checkBox_ImagePreProcessing.Checked = Convert.ToBoolean(Parameters.Parameters["DoImagePreProcessing"].Value);
            comboBox_Color.Text = Parameters.Parameters["PreProcessingColor"].Value;
            floatSingleSlider_PreprocessingColorRatio.Value = Convert.ToDouble(Parameters.Parameters["PreProcessingRatio"].Value);

            checkBox_cellsegmentation.Checked = Convert.ToBoolean(Parameters.Parameters["DoCellSegmentation"].Value);
            checkBox_cellcoredetection.Checked = Convert.ToBoolean(Parameters.Parameters["DoCellCoreDetection"].Value);
            checkBox_contextBasedSeparation.Checked = Convert.ToBoolean(Parameters.Parameters["FastClusterSplitting"].Value);
            checkBox_barbellCellDivision.Checked = Convert.ToBoolean(Parameters.Parameters["BarbellCellDivision"].Value);
            singleSlider_MaxBarbellCellSize.Value = Convert.ToInt32(Parameters.Parameters["BarbellCellDivision_MaxCellSize"].Value);
            checkBox_cellclustersplittingA.Checked = Convert.ToBoolean(Parameters.Parameters["CellClusterSplittingA"].Value);
            checkBox_cellclustersplittingB.Checked = Convert.ToBoolean(Parameters.Parameters["CellClusterSplittingB"].Value);

            checkBox_showCellNumber.Checked = Convert.ToBoolean(Parameters.Parameters["ShowCellNumber"].Value);
            checkBox_ShowCores.Checked = Convert.ToBoolean(Parameters.Parameters["ShowCellCores"].Value);
            checkBox_IgnoreBorderCells.Checked = Convert.ToBoolean(Parameters.Parameters["IgnoreBorderCells"].Value);
            if (checkBox_IgnoreBorderCells.Checked == true)
            {
                singleSlider_MinCellAreaNoIgnoration.Enabled = true;
                singleSlider_BorderContactRatio.Enabled = true;
            }
            else
            {
                singleSlider_MinCellAreaNoIgnoration.Enabled = false;
                singleSlider_BorderContactRatio.Enabled = false;
            }

            singleSlider_MinCellAreaNoIgnoration.Value = Convert.ToInt32(Parameters.Parameters["MaxContactArea"].Value);
            singleSlider_BorderContactRatio.Value = Convert.ToInt32(Parameters.Parameters["MinContactCellArea"].Value);
            checkBox_dynamicRefresh.Checked = Convert.ToBoolean(Parameters.Parameters["IgnoreBorderCells_DynRefresh"].Value);

            checkBox_CalcSaturation.Checked = Convert.ToBoolean(Parameters.Parameters["CalculateSaturation"].Value);

            textBox_CellContourPointsReduction.Text = Parameters.Parameters["CellContourPointsRed"].Value;
            textBox_CoreContourPointsReduction.Text = Parameters.Parameters["CoreContourPointsRed"].Value;

            comboBox_SegmantationMethod.Text = Parameters.Parameters["SegmentationMethod"].Value;

            if (comboBox_SegmantationMethod.Text == "Threshold - Foreground")
            {
                dropDownPanel_Threshold_Foreground.Expanded = true;
                dropDownPanel_Threshold_Background.Expanded = false;
                dropDownPanel_HB.Expanded = false;
            }
            else if (comboBox_SegmantationMethod.Text == "Threshold - Background")
            {
                dropDownPanel_Threshold_Foreground.Expanded = false;
                dropDownPanel_Threshold_Background.Expanded = true;
                dropDownPanel_HB.Expanded = false;
            }
            else if (comboBox_SegmantationMethod.Text == "Histogram Backprojection")
            {
                dropDownPanel_Threshold_Foreground.Expanded = false;
                dropDownPanel_Threshold_Background.Expanded = false;
                dropDownPanel_HB.Expanded = true;
            }

            singleSlider_Area.Value = Convert.ToInt32(Parameters.Parameters["MinCellArea"].Value);

            //-----------------------------------------------------------------------------------------
            //Threshold - Foreground
            //-----------------------------------------------------------------------------------------
            doubleSlider_ThreshRGB.LowerValue = Convert.ToInt32(Parameters.Parameters["Thresh_RGB_LowVal"].Value);
            doubleSlider_ThreshRGB.UpperValue = Convert.ToInt32(Parameters.Parameters["Thresh_RGB_UpVal"].Value);
            doubleSlider_ThreshR.LowerValue = Convert.ToInt32(Parameters.Parameters["Thresh_R_LowVal"].Value);
            doubleSlider_ThreshR.UpperValue = Convert.ToInt32(Parameters.Parameters["Thresh_R_UpVal"].Value);
            doubleSlider_ThreshG.LowerValue = Convert.ToInt32(Parameters.Parameters["Thresh_G_LowVal"].Value);
            doubleSlider_ThreshG.UpperValue = Convert.ToInt32(Parameters.Parameters["Thresh_G_UpVal"].Value);
            doubleSlider_ThreshB.LowerValue = Convert.ToInt32(Parameters.Parameters["Thresh_B_LowVal"].Value);
            doubleSlider_ThreshB.UpperValue = Convert.ToInt32(Parameters.Parameters["Thresh_B_UpVal"].Value);

            checkBox_EditRGBSimultan.Checked = Convert.ToBoolean(Parameters.Parameters["EditRGBChannelsSimultan"].Value);
            checkBox_EditRGBHolesSimultan.Checked = Convert.ToBoolean(Parameters.Parameters["EditRGBHolesSimultan"].Value);

            doubleSlider_HolesThreshRGB.LowerValue = Convert.ToInt32(Parameters.Parameters["Thresh_Holes_RGB_LowVal"].Value);
            doubleSlider_HolesThreshRGB.UpperValue = Convert.ToInt32(Parameters.Parameters["Thresh_Holes_RGB_UpVal"].Value);

            doubleSlider_HolesThreshR.LowerValue = Convert.ToInt32(Parameters.Parameters["Thresh_Holes_R_LowVal"].Value);
            doubleSlider_HolesThreshR.UpperValue = Convert.ToInt32(Parameters.Parameters["Thresh_Holes_R_UpVal"].Value);
            doubleSlider_HolesThreshG.LowerValue = Convert.ToInt32(Parameters.Parameters["Thresh_Holes_G_LowVal"].Value);
            doubleSlider_HolesThreshG.UpperValue = Convert.ToInt32(Parameters.Parameters["Thresh_Holes_G_UpVal"].Value);
            doubleSlider_HolesThreshB.LowerValue = Convert.ToInt32(Parameters.Parameters["Thresh_Holes_B_LowVal"].Value);
            doubleSlider_HolesThreshB.UpperValue = Convert.ToInt32(Parameters.Parameters["Thresh_Holes_B_UpVal"].Value);

            checkBox_FindCellHoles.Checked = Convert.ToBoolean(Parameters.Parameters["FindCellHoles"].Value);
            checkBox_dynActualisation.Checked = Convert.ToBoolean(Parameters.Parameters["DynamicRefresh"].Value);
            //-----------------------------------------------------------------------------------------
            //Threshold - Background
            //-----------------------------------------------------------------------------------------
            doubleSlider_PK_ThreshBackgroundSeg.LowerValue = Convert.ToInt32(Parameters.Parameters["Threshold_Background_LowVal"].Value);
            doubleSlider_PK_ThreshBackgroundSeg.UpperValue = Convert.ToInt32(Parameters.Parameters["Threshold_Background_UpVal"].Value);
            singleSlider_PK_maxCellArea.Value = Convert.ToInt32(Parameters.Parameters["MinCellArea_Background"].Value);
            singleSlider_PK_MaxFillHoleArea.Value = Convert.ToInt32(Parameters.Parameters["MaxAreaFillHoles_Background"].Value);
            checkBox_AutomaticThreshCalc.Checked = Convert.ToBoolean(Parameters.Parameters["AutomaticThresholdCalculation"].Value);

            //-----------------------------------------------------------------------------------------
            //Histogram Backprojection Zellsegmentierung
            //-----------------------------------------------------------------------------------------
            textBox_BinsCells.Text = Parameters.Parameters["Bins_Cells"].Value;
            singleSlider_MinCoreArea.Value = Convert.ToInt32(Parameters.Parameters["MinCoreArea"].Value);
            //-----------------------------------------------------------------------------------------
            //Cell Vitality Parameters
            //-----------------------------------------------------------------------------------------
            comboBox_feature1.Text = Parameters.Parameters["feature1"].Value;
            comboBox_feature2.Text = Parameters.Parameters["feature2"].Value;
            comboBox_feature3.Text = Parameters.Parameters["feature3"].Value;

            textBox_feature1_min.Text = Parameters.Parameters["feature1_min"].Value;
            textBox_feature1_max.Text = Parameters.Parameters["feature1_max"].Value;
            textBox_feature2_min.Text = Parameters.Parameters["feature2_min"].Value;
            textBox_feature2_max.Text = Parameters.Parameters["feature2_max"].Value;
            textBox_feature3_min.Text = Parameters.Parameters["feature3_min"].Value;
            textBox_feature3_max.Text = Parameters.Parameters["feature3_max"].Value;

            int i = 0;
            //Zell-Templates auslesen bis keine mehr vorhanden sind
            flowLayoutPanel_CellSegTemplates.Controls.Clear();
            TemplateCellSegList.Clear();
            while (true)
            {
                try
                {
                    if (Parameters.Parameters["Template_CellSeg_" + Convert.ToString(i)].Value != "")
                    {
                        AddCellTemplateControl(new TImage(Parameters.Parameters["Template_CellSeg_" + Convert.ToString(i)].Value));
                    }
                    i++;
                }
                catch
                {
                    break;
                }
            }
            checkBox_DeleteSatRegions.Checked = Convert.ToBoolean(Parameters.Parameters["DeleteRegionsWithLowSaturationDeviation"].Value);
            floatSingleSlider_SatDeviationFactor.Value = Convert.ToDouble(Parameters.Parameters["SaturationDeviationFactor"].Value);

            comboBox_DCP_Levels.Text = Parameters.Parameters["DCP_Steps"].Value;
            checkBox_dynActualisationDCPs.Checked = Convert.ToBoolean(Parameters.Parameters["DCP_Dynamic_Refresh"].Value);
            //-----------------------------------------------------------------------------------------
            //Histogram Backprojection Kerndetektion
            //-----------------------------------------------------------------------------------------
            textBox_Bins.Text = Parameters.Parameters["Bins_Cores"].Value;
            i = 0;
            //Kern-Templates auslesen bis keine mehr vorhanden sind
            flowLayoutPanel_Templates.Controls.Clear();
            TemplateList.Clear();
            while (true)
            {
                try
                {
                    if (Parameters.Parameters["Template_CoreSeg_" + Convert.ToString(i)].Value != "")
                    {
                        AddSourceControl(new TImage(Parameters.Parameters["Template_CoreSeg_" + Convert.ToString(i)].Value));
                    }
                    i++;
                }
                catch
                {
                    break;
                }
            }
            update();
        }
        void SyncGUIParametersWithParameterClass()
        {
            Parameters.Parameters.Clear();
            //-----------------------------------------------------------------------------------------
            //Allg. Einstellungen
            //-----------------------------------------------------------------------------------------
            Parameters.AddParameter(new Parameter("DoImagePreProcessing", typeof(bool), checkBox_ImagePreProcessing.Checked.ToString()));
            Parameters.AddParameter(new Parameter("PreProcessingColor", typeof(bool), comboBox_Color.Text));
            Parameters.AddParameter(new Parameter("PreProcessingRatio", typeof(int), floatSingleSlider_PreprocessingColorRatio.Value.ToString()));

            Parameters.AddParameter(new Parameter("DoCellSegmentation", typeof(bool), checkBox_cellsegmentation.Checked.ToString()));
            Parameters.AddParameter(new Parameter("DoCellCoreDetection", typeof(bool), checkBox_cellcoredetection.Checked.ToString()));
            Parameters.AddParameter(new Parameter("FastClusterSplitting", typeof(bool), checkBox_contextBasedSeparation.Checked.ToString()));
            Parameters.AddParameter(new Parameter("BarbellCellDivision", typeof(bool), checkBox_barbellCellDivision.Checked.ToString()));
            Parameters.AddParameter(new Parameter("BarbellCellDivision_MaxCellSize", typeof(int), singleSlider_MaxBarbellCellSize.Value.ToString()));
            Parameters.AddParameter(new Parameter("CellClusterSplittingA", typeof(bool), checkBox_cellclustersplittingA.Checked.ToString()));
            Parameters.AddParameter(new Parameter("CellClusterSplittingB", typeof(bool), checkBox_cellclustersplittingB.Checked.ToString()));

            Parameters.AddParameter(new Parameter("ShowCellNumber", typeof(bool), checkBox_showCellNumber.Checked.ToString()));
            Parameters.AddParameter(new Parameter("ShowCellCores", typeof(bool), checkBox_ShowCores.Checked.ToString()));
            Parameters.AddParameter(new Parameter("IgnoreBorderCells", typeof(bool), checkBox_IgnoreBorderCells.Checked.ToString()));
            Parameters.AddParameter(new Parameter("MaxContactArea", typeof(int), singleSlider_MinCellAreaNoIgnoration.Value.ToString()));
            Parameters.AddParameter(new Parameter("MinContactCellArea", typeof(int), singleSlider_BorderContactRatio.Value.ToString()));
            Parameters.AddParameter(new Parameter("IgnoreBorderCells_DynRefresh", typeof(bool), checkBox_dynamicRefresh.Checked.ToString()));


            Parameters.AddParameter(new Parameter("CalculateSaturation", typeof(bool), checkBox_CalcSaturation.Checked.ToString()));

            Parameters.AddParameter(new Parameter("CellContourPointsRed", typeof(int), textBox_CellContourPointsReduction.Text));
            Parameters.AddParameter(new Parameter("CoreContourPointsRed", typeof(int), textBox_CoreContourPointsReduction.Text));

            Parameters.AddParameter(new Parameter("SegmentationMethod", typeof(string), comboBox_SegmantationMethod.Text));
            Parameters.AddParameter(new Parameter("MinCellArea", typeof(int), singleSlider_Area.Value.ToString()));
            //-----------------------------------------------------------------------------------------
            //Threshold - Foreground
            //-----------------------------------------------------------------------------------------
            Parameters.AddParameter(new Parameter("Thresh_RGB_LowVal", typeof(byte), doubleSlider_ThreshRGB.LowerValue.ToString()));
            Parameters.AddParameter(new Parameter("Thresh_RGB_UpVal", typeof(byte), doubleSlider_ThreshRGB.UpperValue.ToString()));
            Parameters.AddParameter(new Parameter("Thresh_R_LowVal", typeof(byte), doubleSlider_ThreshR.LowerValue.ToString()));
            Parameters.AddParameter(new Parameter("Thresh_R_UpVal", typeof(byte), doubleSlider_ThreshR.UpperValue.ToString()));
            Parameters.AddParameter(new Parameter("Thresh_G_LowVal", typeof(byte), doubleSlider_ThreshG.LowerValue.ToString()));
            Parameters.AddParameter(new Parameter("Thresh_G_UpVal", typeof(byte), doubleSlider_ThreshG.UpperValue.ToString()));
            Parameters.AddParameter(new Parameter("Thresh_B_LowVal", typeof(byte), doubleSlider_ThreshB.LowerValue.ToString()));
            Parameters.AddParameter(new Parameter("Thresh_B_UpVal", typeof(byte), doubleSlider_ThreshB.UpperValue.ToString()));

            Parameters.AddParameter(new Parameter("EditRGBChannelsSimultan", typeof(bool), checkBox_EditRGBSimultan.Checked.ToString()));
            Parameters.AddParameter(new Parameter("EditRGBHolesSimultan", typeof(bool), checkBox_EditRGBHolesSimultan.Checked.ToString()));

            Parameters.AddParameter(new Parameter("Thresh_Holes_RGB_LowVal", typeof(byte), doubleSlider_HolesThreshRGB.LowerValue.ToString()));
            Parameters.AddParameter(new Parameter("Thresh_Holes_RGB_UpVal", typeof(byte), doubleSlider_HolesThreshRGB.UpperValue.ToString()));
            Parameters.AddParameter(new Parameter("Thresh_Holes_R_LowVal", typeof(byte), doubleSlider_HolesThreshR.LowerValue.ToString()));
            Parameters.AddParameter(new Parameter("Thresh_Holes_R_UpVal", typeof(byte), doubleSlider_HolesThreshR.UpperValue.ToString()));
            Parameters.AddParameter(new Parameter("Thresh_Holes_G_LowVal", typeof(byte), doubleSlider_HolesThreshG.LowerValue.ToString()));
            Parameters.AddParameter(new Parameter("Thresh_Holes_G_UpVal", typeof(byte), doubleSlider_HolesThreshG.UpperValue.ToString()));
            Parameters.AddParameter(new Parameter("Thresh_Holes_B_LowVal", typeof(byte), doubleSlider_HolesThreshB.LowerValue.ToString()));
            Parameters.AddParameter(new Parameter("Thresh_Holes_B_UpVal", typeof(byte), doubleSlider_HolesThreshB.UpperValue.ToString()));

            Parameters.AddParameter(new Parameter("FindCellHoles", typeof(bool), checkBox_FindCellHoles.Checked.ToString()));
            Parameters.AddParameter(new Parameter("DynamicRefresh", typeof(bool), checkBox_dynActualisation.Checked.ToString()));
            //-----------------------------------------------------------------------------------------
            //Threshold - Background
            //-----------------------------------------------------------------------------------------
            Parameters.AddParameter(new Parameter("Threshold_Background_LowVal", typeof(byte), doubleSlider_PK_ThreshBackgroundSeg.LowerValue.ToString()));
            Parameters.AddParameter(new Parameter("Threshold_Background_UpVal", typeof(byte), doubleSlider_PK_ThreshBackgroundSeg.UpperValue.ToString()));
            Parameters.AddParameter(new Parameter("MinCellArea_Background", typeof(int), singleSlider_PK_maxCellArea.Value.ToString()));
            Parameters.AddParameter(new Parameter("MaxAreaFillHoles_Background", typeof(int), singleSlider_PK_MaxFillHoleArea.Value.ToString()));
            Parameters.AddParameter(new Parameter("AutomaticThresholdCalculation", typeof(bool), checkBox_AutomaticThreshCalc.Checked.ToString()));
            //-----------------------------------------------------------------------------------------
            //Histogram Backprojection Zellsegmentierung
            //-----------------------------------------------------------------------------------------
            Parameters.AddParameter(new Parameter("Bins_Cells", typeof(int), textBox_BinsCells.Text));
            for (int i = 0; i < TemplateCellSegList.Count; i++)
            {
                Parameters.AddParameter(new Parameter("Template_CellSeg_" + Convert.ToString(i), typeof(string), TemplateCellSegList[i].ImagePath));
            }
            Parameters.AddParameter(new Parameter("DCP_Steps", typeof(int), comboBox_DCP_Levels.Text));
            Parameters.AddParameter(new Parameter("DCP_Dynamic_Refresh", typeof(bool), checkBox_dynActualisationDCPs.Checked.ToString()));
            //-----------------------------------------------------------------------------------------
            //Saturation Properties
            //-----------------------------------------------------------------------------------------
            Parameters.AddParameter(new Parameter("DeleteRegionsWithLowSaturationDeviation", typeof(bool), checkBox_DeleteSatRegions.Checked.ToString()));
            Parameters.AddParameter(new Parameter("SaturationDeviationFactor", typeof(float), floatSingleSlider_SatDeviationFactor.Value.ToString()));
            //-----------------------------------------------------------------------------------------
            //Cell Vitality Parameters
            //-----------------------------------------------------------------------------------------
            Parameters.AddParameter(new Parameter("feature1", typeof(string), comboBox_feature1.Text));
            Parameters.AddParameter(new Parameter("feature2", typeof(string), comboBox_feature2.Text));
            Parameters.AddParameter(new Parameter("feature3", typeof(string), comboBox_feature3.Text));
            Parameters.AddParameter(new Parameter("feature1_min", typeof(string), textBox_feature1_min.Text));
            Parameters.AddParameter(new Parameter("feature1_max", typeof(string), textBox_feature1_max.Text));
            Parameters.AddParameter(new Parameter("feature2_min", typeof(string), textBox_feature2_min.Text));
            Parameters.AddParameter(new Parameter("feature2_max", typeof(string), textBox_feature2_max.Text));
            Parameters.AddParameter(new Parameter("feature3_min", typeof(string), textBox_feature3_min.Text));
            Parameters.AddParameter(new Parameter("feature3_max", typeof(string), textBox_feature3_max.Text));            
            //-----------------------------------------------------------------------------------------
            //Histogram Backprojection Kerndetektion
            //-----------------------------------------------------------------------------------------
            Parameters.AddParameter(new Parameter("Bins_Cores", typeof(int), textBox_Bins.Text));
            Parameters.AddParameter(new Parameter("MinCoreArea", typeof(int), Convert.ToString(singleSlider_MinCoreArea.Value)));
            for (int i = 0; i < TemplateList.Count; i++)
            {
                Parameters.AddParameter(new Parameter("Template_CoreSeg_" + Convert.ToString(i), typeof(string), TemplateList[i].ImagePath));
            }
        }

        void mainWindow_ObjectDeleted(object sender, SimpleCADControl.GeoObjectEventArgs e)
        {
            try
            {
                foreach (var item in cellDataPolyCollection.Keys)
                {
                    if (cellDataPolyCollection[item] == e.Obj)
                    {
                        dataGridView_CellStatistics.Rows.Remove(item);
                        cellPolyCollection.Remove((Polygon)e.Obj);
                        cellDataPolyCollection.Remove(item);
                    }
                }
            }
            catch { }
        }

        void mainWindow_ObjectClicked(object sender, SimpleCADControl.GeoObjectEventArgs e)
        {
            try
            {
                foreach (var item in cellDataPolyCollection.Keys)
                {
                    if (cellDataPolyCollection[item] == e.Obj)
                    {
                        item.Selected = true;
                    }
                }
            }
            catch { }
        }

        public void AddSourceControl(TImage img)
        {
            if (InvokeRequired)
            {
                Invoke(new AddSourceControlDelegate(AddSourceControl), img);
                return;
            }
            CustomControls.HB_Template_Control control = new CustomControls.HB_Template_Control();
            if (img.control.inserted == false)
            {
                img.control.inserted = true;
                img.control.Name = Convert.ToString(flowLayoutPanel_Templates.Controls.Count + 1);
                img.control.Text_Box = "Source Item " + Convert.ToString(flowLayoutPanel_Templates.Controls.Count + 1);
                img.control.Image = img.Image;
                img.control.classificationColor = Color.White;
                img.control.ControlClicked += new EventHandler<MouseEventArgs>(control_ControlClicked);
                switch (img.Pixelformat)
                {
                    case PixelFormat.Format24bppRgb: img.control.Text_Quality = "24bit RGB"; break;
                    case PixelFormat.Format32bppArgb: img.control.Text_Quality = "32bit ARGB"; break;
                    case PixelFormat.Format48bppRgb: img.control.Text_Quality = "48bit RGB"; break;
                    case PixelFormat.Format64bppArgb: img.control.Text_Quality = "64bit ARGB"; break;
                    case PixelFormat.Format64bppPArgb: img.control.Text_Quality = "64bitPARGB"; break;
                    case PixelFormat.Format1bppIndexed: img.control.Text_Quality = "1bit Ind."; break;
                    case PixelFormat.Format4bppIndexed: img.control.Text_Quality = "4bit Ind."; break;
                    case PixelFormat.Format8bppIndexed: img.control.Text_Quality = "8bit Ind."; break;
                    case PixelFormat.Format16bppGrayScale: img.control.Text_Quality = "16bitGRAY"; break;
                }
                img.control.Text_Width = Convert.ToString(img.Width);
                img.control.Text_Height = Convert.ToString(img.Height);
                img.control.Text_Size = TemplateFileName;
                img.control.ContextMenuStrip = contextMenuStrip1;
                flowLayoutPanel_Templates.Controls.Add(img.control);
                TemplateList.Add(img);
                flowLayoutPanel_Templates.Show();
            }
            else
            {
                MessageBox.Show("Image already inserted in a control-list! Make a copy when you want to insert the image in different control-lists.");
            }
        }
        public void AddCellTemplateControl(TImage img)
        {
            if (InvokeRequired)
            {
                Invoke(new AddSourceControlDelegate(AddCellTemplateControl), img);
                return;
            }
            CustomControls.HB_Template_Control control = new CustomControls.HB_Template_Control();
            if (img.control.inserted == false)
            {
                img.control.inserted = true;
                img.control.Name = Convert.ToString(flowLayoutPanel_Templates.Controls.Count + 1);
                img.control.Text_Box = "Source Item " + Convert.ToString(flowLayoutPanel_Templates.Controls.Count + 1);
                img.control.Image = img.Image;
                img.control.classificationColor = Color.White;
                img.control.ControlClicked += new EventHandler<MouseEventArgs>(control_ControlClicked);
                switch (img.Pixelformat)
                {
                    case PixelFormat.Format24bppRgb: img.control.Text_Quality = "24bit RGB"; break;
                    case PixelFormat.Format32bppArgb: img.control.Text_Quality = "32bit ARGB"; break;
                    case PixelFormat.Format48bppRgb: img.control.Text_Quality = "48bit RGB"; break;
                    case PixelFormat.Format64bppArgb: img.control.Text_Quality = "64bit ARGB"; break;
                    case PixelFormat.Format64bppPArgb: img.control.Text_Quality = "64bitPARGB"; break;
                    case PixelFormat.Format1bppIndexed: img.control.Text_Quality = "1bit Ind."; break;
                    case PixelFormat.Format4bppIndexed: img.control.Text_Quality = "4bit Ind."; break;
                    case PixelFormat.Format8bppIndexed: img.control.Text_Quality = "8bit Ind."; break;
                    case PixelFormat.Format16bppGrayScale: img.control.Text_Quality = "16bitGRAY"; break;
                }
                img.control.Text_Width = Convert.ToString(img.Width);
                img.control.Text_Height = Convert.ToString(img.Height);
                img.control.ContextMenuStrip = contextMenuStrip1;
                flowLayoutPanel_CellSegTemplates.Controls.Add(img.control);
                TemplateCellSegList.Add(img);
                flowLayoutPanel_CellSegTemplates.Show();
            }
            else
            {
                MessageBox.Show("Image already inserted in a control-list! Make a copy when you want to insert the image in different control-lists.");
            }
        }
        public void AddSourceControl(TImage img, Color color)
        {
            if (InvokeRequired)
            {
                Invoke(new AddSourceControlDelegate2(AddSourceControl), img, color);
                return;
            }
            CustomControls.HB_Template_Control control = new CustomControls.HB_Template_Control();
            if (img.control.inserted == false)
            {
                img.control.inserted = true;
                img.control.Name = Convert.ToString(flowLayoutPanel_Templates.Controls.Count + 1);
                img.control.Text_Box = "Source Item " + Convert.ToString(flowLayoutPanel_Templates.Controls.Count + 1);
                img.control.Image = img.Image;
                img.control.classificationColor = color;
                img.control.ControlClicked += new EventHandler<MouseEventArgs>(control_ControlClicked);
                switch (img.Pixelformat)
                {
                    case PixelFormat.Format24bppRgb: img.control.Text_Quality = "24bit RGB"; break;
                    case PixelFormat.Format32bppArgb: img.control.Text_Quality = "32bit ARGB"; break;
                    case PixelFormat.Format48bppRgb: img.control.Text_Quality = "48bit RGB"; break;
                    case PixelFormat.Format64bppArgb: img.control.Text_Quality = "64bit ARGB"; break;
                    case PixelFormat.Format64bppPArgb: img.control.Text_Quality = "64bitPARGB"; break;
                    case PixelFormat.Format1bppIndexed: img.control.Text_Quality = "1bit Ind."; break;
                    case PixelFormat.Format4bppIndexed: img.control.Text_Quality = "4bit Ind."; break;
                    case PixelFormat.Format8bppIndexed: img.control.Text_Quality = "8bit Ind."; break;
                    case PixelFormat.Format16bppGrayScale: img.control.Text_Quality = "16bitGRAY"; break;
                }
                img.control.Text_Width = Convert.ToString(img.Width);
                img.control.Text_Height = Convert.ToString(img.Height);
                img.control.ContextMenuStrip = contextMenuStrip1;
                flowLayoutPanel_Templates.Controls.Add(img.control);
                TemplateList.Add(img);
                flowLayoutPanel_Templates.Show();
            }
            else
            {
                MessageBox.Show("Image already inserted in a control-list! Make a copy when you want to insert the image in different control-lists.");
            }
        }

        private List<cellData> calcCellStatistics(List<cellData> cells, bool calcSaturation)
        {
            HObject img_Saturation_HAL;
            HTuple area, row, col, circularity, compactness;
            HTuple saturation, saturationDeviation;

            TImage img_Saturation = imageWorker.calcRGBImgSaturation(new TImage(mainWindow.Image));

            HalconDotNet.HOperatorSet.GenImageInterleaved(out img_Saturation_HAL, img_Saturation.firstPixel, "bgr",
                                                          img_Saturation.Width, img_Saturation.Height, 0, "byte",
                                                          0, 0, 0, 0, -1, 0);
            for (int i = 0; i < cells.Count; i++)
            {
                cellStatistics stat = new cellStatistics();
                HOperatorSet.AreaCenter(cells[i].cellRegion, out area, out row, out col);
                stat.cellArea = area.D;
                HOperatorSet.Compactness(cells[i].cellRegion, out compactness);
                stat.cellForm = compactness.D;
                HOperatorSet.Circularity(cells[i].cellRegion, out circularity);
                stat.circularity = circularity.D;
                //Sättigung aller Zellen nur einmal berechnen
                if (calcSaturation == true)
                {
                    HalconFunctions.calcCellSaturation(cells[i].cellRegion, img_Saturation_HAL, out saturation, out saturationDeviation);
                    stat.saturation = saturation;
                    stat.saturationDeviation = saturationDeviation;
                }
                else
                {
                    stat.saturation = 0;
                    stat.saturationDeviation = 0;
                }
                cells[i].statistics = stat;
            }
            return cells;
        }

        private cellData calcCellStatistics(cellData cell, bool calcSaturation, HObject img)
        {
            HTuple area, row, col, compactness, circularity;
            HTuple saturation, saturationDeviation;

            cellData newcell = new cellData();
            cellStatistics stat = new cellStatistics();
            HOperatorSet.AreaCenter(cell.cellRegion, out area, out row, out col);
            stat.cellArea = area.D;
            HOperatorSet.Compactness(cell.cellRegion, out compactness);
            stat.cellForm = compactness.D;
            HOperatorSet.Circularity(cell.cellRegion, out circularity);
            stat.circularity = circularity.D;
            //Farbsättigung berechnen 
            if (calcSaturation == true)
            {
                HalconFunctions.calcCellSaturation(cell.cellRegion, img, out saturation, out saturationDeviation);
                stat.saturation = saturation;
                stat.saturationDeviation = saturationDeviation;
            }
            else
            {
                stat.saturation = 0;
                stat.saturationDeviation = 0;
            }
            newcell.cellRegion = cell.cellRegion;
            newcell.cellContour = cell.cellContour;
            newcell.CoreInfo = cell.CoreInfo;
            stat.coreCount = cell.CoreInfo.Count;
            newcell.isCluster = cell.isCluster;
            newcell.nr = cell.nr;
            newcell.statistics = stat;

            return newcell;
        }

        private double calcValidProcentFactor(double deviationValue, double procentMin, double procentMax)
        {
            double val = procentMin + ((deviationValue / 255) * (procentMax - procentMin));
            return (procentMin + ((deviationValue / 255) * (procentMax - procentMin)));
        }

        private List<cellData> eleminateBackgroundNoise(List<cellData> cells, double deviationFactor)
        {
            HTuple cellArea, cellRow, cellCol;
            List<int> eleminatedCellIndizes = new List<int>();
            double meanDeviationBeforeOutlierDeleting = 0;
            double meanDeviationAfterOutlierDeleting = 0;
            double sigma = 0;
            try
            {
                //Mittelwert der Farbsättigung aller Objekte bestimmen -> Normalverteilung wird angenommen
                for (int i = 0; i < cells.Count; i++)
                {
                    meanDeviationBeforeOutlierDeleting = meanDeviationBeforeOutlierDeleting + cells[i].statistics.saturation;
                }
                meanDeviationBeforeOutlierDeleting = meanDeviationBeforeOutlierDeleting / cells.Count;
                //Standardabweichung berechnen
                for (int i = 0; i < cells.Count; i++)
                {
                    sigma = sigma + ((meanDeviationBeforeOutlierDeleting - cells[i].statistics.saturation) * (meanDeviationBeforeOutlierDeleting - cells[i].statistics.saturation));
                }
                sigma = Math.Sqrt(sigma / cells.Count);
                //Ausreißer für die erneute Mittelwertbildung ignorieren
                int counter = 0;
                for (int i = 0; i < cells.Count; i++)
                {
                    //Wenn die Farbsättigung innerhalb des 68,3% Intervalls um den Erwartungswert liegt wird der Wert für die Mittelwertbildung herangezogen
                    if ((cells[i].statistics.saturation >= meanDeviationBeforeOutlierDeleting - sigma) && (cells[i].statistics.saturation <= meanDeviationBeforeOutlierDeleting + sigma))
                    {
                        counter++;
                        meanDeviationAfterOutlierDeleting = meanDeviationAfterOutlierDeleting + cells[i].statistics.saturation;
                    }
                }
                meanDeviationAfterOutlierDeleting = meanDeviationAfterOutlierDeleting / counter;

                for (int i = 0; i < cells.Count; i++)
                {
                    if ((cells[i].statistics.saturation <= meanDeviationAfterOutlierDeleting * deviationFactor))
                    {
                        cells.RemoveAt(i);
                        i--;
                    }
                }
                //2. Regel: Die n kleinsten Werte die maximal 10% Abweichung zum kleinsten Wert haben überprüfen ob sie
                //einen mind. 15% geringeren Wert haben als die Zelle mit dem nächst höheren Wert für die Standardabw. der Farbsättigung

                //1. Neue sortierte Zellliste erstellen
                List<int> sortedCellIndizes = new List<int>();
                double minVal;
                int index;
                bool cellAlreadySorted = false;
                for (int j = 0; j < cells.Count; j++)
                {
                    index = -1;
                    minVal = 99999999;
                    for (int i = 0; i < cells.Count; i++)
                    {
                        for (int k = 0; k < sortedCellIndizes.Count; k++)
                        {
                            if (i == sortedCellIndizes[k])
                            {
                                cellAlreadySorted = true;
                                break;
                            }
                        }
                        if ((cells[i].statistics.saturation <= minVal) && (cellAlreadySorted == false))
                        {
                            minVal = cells[i].statistics.saturation;
                            index = i;
                        }
                        cellAlreadySorted = false;
                    }
                    if (index > -1)
                    {
                        sortedCellIndizes.Add(index);
                    }
                }
                //2. Regel macht nur sinn, wenn eine erhöhte Varianz der Werte auftritt, sonst sind die Werte zu ähnlich und
                //das würde dazu führen, dass ähnliche Farbwerte gesammelt werden und diese evtl. 15% vom nächstgrößeren Wert unterscheiden
                //Eine hohe Varianz sollte demnach nur auftreten wenn sich Bildartefakte im Bild befinden
                //2. Die kleinsten n Werte, die sich um weniger als 10% vom kleinsten Wert unterscheiden in einer Liste zusammenfassen
                List<cellData> similarCells = new List<cellData>();
                if (sortedCellIndizes.Count > 0)
                    similarCells.Add(cells[sortedCellIndizes[0]]);
                for (int i = 1; i < sortedCellIndizes.Count; i++)
                {
                    //Der aktuelle Wert muss kleiner als der kleinste Wert * 1.1 bis 1.5 (abh. von Wertgröße) sein und der aktuelle Wert darf max. 10% kleiner als der nächst größere sein
                    //Wenn der nächstgrößere Wert über 10% größer ist -> Wird nicht mehr zur Liste hinzugefügt
                    if (cells[sortedCellIndizes[i]].statistics.saturation <= cells[sortedCellIndizes[0]].statistics.saturation * (1 + calcValidProcentFactor(cells[sortedCellIndizes[0]].statistics.saturation, 0.1, 0.4))
                        && (cells[sortedCellIndizes[i - 1]].statistics.saturation >= cells[sortedCellIndizes[i]].statistics.saturation * 0.9))
                    {
                        similarCells.Add(cells[sortedCellIndizes[i]]);
                    }
                    else
                        break;
                }
                //Wenn keine ähnlichen Werte (>1 Wert) gefunden wurden, handelt es sich maximal um einen einzigen Ausreißer. Wenn es ein
                //Bildartefakt gibt, kann es nur noch der erste Zellbereich in der sortierten Liste sein. Deshalb prüfen, ob der 
                //Wert für die Farbsättigung des kleinsten Wertes mind. 12,5% kleiner ist als der 2. kleinste Wert.
                //Wenn ja -> Zellbereich löschen, wenn nein -> Zellbereich bleibt erhalten
                if (similarCells.Count < 2)
                {
                    if (cells[sortedCellIndizes[1]].statistics.saturation * 0.875 >= cells[sortedCellIndizes[0]].statistics.saturation)
                    {
                        HOperatorSet.AreaCenter(cells[sortedCellIndizes[0]].cellRegion, out cellArea, out cellRow, out cellCol);
                        //Objekte > 20.000Pixel werden nicht gelöscht, da wir Annehmen dass es keine so großen Bildartefakte gibt, die Wahrscheinlichkeit ist hoch dass es sich
                        //um eine blasse Zelle handelt
                        if (cellArea < 20000)
                        {
                            //Wenn das Objekt < 20.000 Pixel ist, muss es eine Kreisförmigkeit < 0.1 aufweisen um gelöscht zu werden, ausser sie ist < 1000 Pixel. Oder das Objekt weicht um mind. 20% vom nächst kleineren Sättigungswert ab
                            if ((cellArea < 20000) && ((cells[sortedCellIndizes[0]].statistics.circularity < 0.1) || (cellArea < 1000) || (cells[sortedCellIndizes[1]].statistics.saturation * 0.8 >= cells[sortedCellIndizes[0]].statistics.saturation)))
                                eleminatedCellIndizes.Add(sortedCellIndizes[0]);
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < similarCells.Count; i++)
                    {
                        //Um zu verhindern dass bei gering ansteigenden Werten eine große Gruppe ähnlicher Werte entsteht,so dass der nächstkleinste Wert dann
                        //aber doch ziemlich unterschiedlich zum aller ersten Wert in der Ähnlichkeitsliste ist und dieser dann fälschlicherweise gelöscht wird
                        //da es z.B. doch alles Zellen sind -> hier abfragen dass der größte Wert in der Ähnlichkeitsliste trotzdem noch 10% unter dem nächstgrößten Wert
                        //liegen muss. So wird sichergestellt dass eine abgetrennte Ähnlichkeitsgruppe existiert, in der sich mehrere Kratzer befinden könnten
                        if (similarCells[similarCells.Count - 1].statistics.saturation <= 0.9 * cells[sortedCellIndizes[similarCells.Count]].statistics.saturation)
                        {
                            if (cells[sortedCellIndizes[similarCells.Count]].statistics.saturation * 0.875 >= cells[sortedCellIndizes[i]].statistics.saturation)
                            {
                                //HOperatorSet.AreaCenter(cells[sortedCellIndizes[similarCells.Count]].cellRegion, out cellArea, out cellRow, out cellCol);
                                HOperatorSet.AreaCenter(cells[sortedCellIndizes[i]].cellRegion, out cellArea, out cellRow, out cellCol);
                                //Alleine nach Ausreissern bei der Farbsättigung zu suchen reicht nicht aus, da teilweise auch etwas "blasse" Zellen vorhanden sind
                                //und so aussortiert würden. Deshalb zusätzlich noch Formmerkmale abfragen, da Polierkratzer i.d.R. eine andere Form aufweisen
                                //als Zellen der Linie L929 oder vergleichbare. (im Vgl. zu Kratzern hohe kreisförmigkeit). Selten kann es vorkommen das auch rundliche Bildartefakte
                                //erscheinen. Deshalb wird die Regel so erweitert dass auch beliebig geformte Objekte eleminiert werden können, wenn sie
                                //einen Farbsättigungsunterschied von mind. 20% zum nächsthöheren Wert nach der Ähnlichkeitsliste besitzen
                                //Bei länglichen Zelllinien hilft die Abfrage nach Formmerkmalen dann wahrscheinlich nicht mehr so gut, in dem Fall bietet sich dann an, 
                                //das zulässige Intervall für die Farbsättigung zu erweitern um auszuschließen das Zellen eleminiert werden
                                if ((cellArea < 20000) && ((cells[sortedCellIndizes[i]].statistics.circularity <= 0.1) || (cells[sortedCellIndizes[similarCells.Count]].statistics.saturation * 0.8 >= cells[sortedCellIndizes[i]].statistics.saturation)))
                                    eleminatedCellIndizes.Add(sortedCellIndizes[i]);
                            }
                        }
                    }
                }
                if (eleminatedCellIndizes.Count > 0)
                {
                    //Liste mit den zu löschenden Zell-Indizes aufsteigend sortieren, da nach dem Löschen einer Zelle aus der Zellliste
                    //die nachfolgend gespeicherten Indizes um eins verringert werden müssen etc.
                    eleminatedCellIndizes.Sort();
                    //Zellen aus der Liste löschen und Zellnummern neu vergeben
                    for (int i = 0; i < eleminatedCellIndizes.Count; i++)
                    {
                        cells.RemoveAt(eleminatedCellIndizes[i] - i);
                    }
                    for (int i = 0; i < cells.Count; i++)
                    {
                        cells[i].nr = i + 1;
                    }
                }
                return cells;
            }
            catch (System.Exception ex)
            {
                //sortedEleminatedCellIndizes = null;
                eleminatedCellIndizes = null;
                MessageBox.Show("Fehler in Funktion eleminateBackgroundNoise " + ex.Message);
                return cells;
            }
        }
        /// <summary>
        /// Wenn auf das Template-Control geklickt wurde wird dieses Event hier abonniert und als erstes
        /// die clicked-Properties aller Controls auf false gesetzt. Im Event innerhalb des Controls wird dann
        /// das Clicked-Property auf true gesetzt. So wird sichergestellt, dass immer nur ein Control-Property 
        /// clicked = true besitzt
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void control_ControlClicked(object sender, MouseEventArgs e)
        {
            //Alle Clicked-Properites der Controls zurücksetzen
            for (int i = 0; i < flowLayoutPanel_Templates.Controls.Count; i++)
            {
                ((CustomControls.HB_Template_Control)flowLayoutPanel_Templates.Controls[i]).clicked = false;
            }
        }

        private void ImportTemplateImage()
        {
            openFileDialog1.Filter = "Alle kompatiblen Dateien (.jpg,.bmp,.png,.tif,.gif)|*.jpg;*.bmp;*.png;*.tif;*.gif|Bitmap (.bmp)|*.bmp";

            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                foreach (String filename in openFileDialog1.FileNames)
                {
                    TemplateFileName = openFileDialog1.SafeFileName;
                    AddSourceControl(new TImage(filename));
                }
            }
        }

        private int countcheckedBoxes()
        {
            int retVal = 0;

            if (checkBox_cellsegmentation.Checked == true)
                retVal++;
            if (checkBox_cellcoredetection.Checked == true)
                retVal++;
            if ((checkBox_cellclustersplittingA.Checked == true) || (checkBox_cellclustersplittingB.Checked == true))
                retVal++;

            return retVal;
        }

        private void B_Run_Click(object sender, EventArgs e)
        {
            if (singleSlider_Area.Value == 0)
                return;
            if (inProcess == false)
            {
                try
                {
                    statusBar_Steps.TbManager.SetProgressState(Microsoft.WindowsAPICodePack.Taskbar.TaskbarProgressBarState.Normal);
                    this.Cursor = busyCursor;
                    inProcess = true;
                    HOperatorSet.ClearWindow(window);
                    HObject halImg;
                    HOperatorSet.ReadImage(out halImg, mainWindow.Image);
                    HOperatorSet.SetPart(window, 0, 0, -1, -1);
                    HOperatorSet.DispObj(halImg, window);
                    HOperatorSet.SetPart(window, 0, 0, -1, -1);
                    HOperatorSet.DispObj(halImg, window);
                    //Step-Statusbar initialisisieren
                    statusBar_Steps.Breakpoints.Clear();
                    cellDataPolyCollection.Clear();
                    cellPolyCollection.Clear();
                    dataGridView_CellStatistics.Rows.Clear();
                    statusBar_Steps.Value = 0;

                    switch (countcheckedBoxes())
                    {
                        case 1:
                            if (checkBox_cellsegmentation.Checked == true)
                            {
                                BreakPoint ptn1 = new BreakPoint();
                                ptn1.ProgressPosition = 1;
                                ptn1.Radius = statusBar_Steps.Height / 4;
                                statusBar_Steps.Add(ptn1);
                            }
                            statusBar_Steps.Invalidate();
                            break;
                        case 2: if (checkBox_cellsegmentation.Checked == true)
                            {
                                BreakPoint ptn1 = new BreakPoint();
                                ptn1.ProgressPosition = 0.47;
                                ptn1.Radius = statusBar_Steps.Height / 4;
                                statusBar_Steps.Add(ptn1);
                            }
                            if (checkBox_cellcoredetection.Checked == true)
                            {
                                BreakPoint ptn1 = new BreakPoint();
                                ptn1.ProgressPosition = 1;
                                ptn1.Radius = statusBar_Steps.Height / 4;
                                statusBar_Steps.Add(ptn1);
                            }
                            statusBar_Steps.Invalidate();
                            break;
                        case 3: if (checkBox_cellsegmentation.Checked == true)
                            {
                                BreakPoint ptn1 = new BreakPoint();
                                ptn1.ProgressPosition = 0.33;
                                ptn1.Radius = 15;
                                statusBar_Steps.Add(ptn1);
                            }
                            if (checkBox_cellcoredetection.Checked == true)
                            {
                                BreakPoint ptn1 = new BreakPoint();
                                ptn1.ProgressPosition = 0.66;
                                //ptn1.Radius =statusBar_Steps.Height / 4;
                                ptn1.Radius = 15;
                                statusBar_Steps.Add(ptn1);
                            }
                            if ((checkBox_cellclustersplittingA.Checked == true) || (checkBox_cellclustersplittingB.Checked == true))
                            {
                                BreakPoint ptn1 = new BreakPoint();
                                ptn1.Radius = 15;
                                ptn1.ProgressPosition = 1 - ((double)ptn1.Radius / statusBar_Steps.Width);
                                statusBar_Steps.Add(ptn1);
                            }
                            statusBar_Steps.Invalidate();
                            break;
                    }
                    if ((mainWindow.Image != null) && (mainWindow.Image != "") && (checkBox_cellsegmentation.Checked == true))
                    {
                        //Zuerst mögliche GeoObjekte von einer vorherigen Ausführung löschen
                        mainWindow.GeoObjects.Clear();
                        //Neu generierte Zellen durch den Zelltrennungsalgo wieder löschen
                        newCellList.Clear();
                        cells.Clear();
                        mainWindow.Refresh();

                        ParameterizedThreadStart pts = new ParameterizedThreadStart(runAlgo);
                        thread = new Thread(pts);

                        Object[] pars = new Object[32];
                        pars[0] = comboBox_SegmantationMethod.Text;
                        pars[1] = Convert.ToInt32(comboBox_DCP_Levels.Text);
                        pars[2] = doubleSlider_PK_ThreshBackgroundSeg.LowerValue;
                        pars[3] = doubleSlider_PK_ThreshBackgroundSeg.UpperValue;
                        pars[4] = singleSlider_PK_maxCellArea.Value;
                        pars[5] = singleSlider_PK_MaxFillHoleArea.Value;
                        pars[6] = textBox_BinsCells.Text;
                        pars[7] = textBox_CellContourPointsReduction.Text;
                        pars[8] = textBox_CoreContourPointsReduction.Text;
                        pars[9] = singleSlider_MinCoreArea.Value;
                        pars[10] = checkBox_showCellNumber.Checked;
                        pars[11] = checkBox_DeleteSatRegions.Checked;
                        pars[12] = floatSingleSlider_SatDeviationFactor.Value;
                        pars[13] = singleSlider_MinCellAreaNoIgnoration.Value;
                        pars[14] = singleSlider_BorderContactRatio.Value;
                        pars[15] = checkBox_contextBasedSeparation.Checked;
                        pars[16] = checkBox_cellclustersplittingB.Checked;
                        pars[17] = singleSlider_minArea_cellGrowthSimulation.Value;
                        pars[18] = checkBox_barbellCellDivision.Checked;
                        pars[19] = checkBox_ImagePreProcessing.Checked;
                        pars[20] = floatSingleSlider_PreprocessingColorRatio.Value;
                        pars[21] = comboBox_Color.SelectedValue;
                        pars[22] = singleSlider_MaxBarbellCellSize.Value;
                        pars[23] = comboBox_feature1.Text;
                        pars[24] = comboBox_feature2.Text;
                        pars[25] = comboBox_feature3.Text;
                        pars[26] = textBox_feature1_min.Text;
                        pars[27] = textBox_feature1_max.Text;
                        pars[28] = textBox_feature2_min.Text;
                        pars[29] = textBox_feature2_max.Text;
                        pars[30] = textBox_feature3_min.Text;
                        pars[31] = textBox_feature3_max.Text;

                        Application.DoEvents();

                        thread.Start(pars);
                    }
                    else
                    {
                        inProcess = false;
                        Cursor = Cursors.Default;
                    }
                }
                catch
                {
                    inProcess = false;
                    Cursor = Cursors.Default;
                }
            }
        }

        private void editingCellContoursToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (editingCellContoursToolStripMenuItem.Checked)
            {
                for (int i = 0; i < mainWindow.GeoObjects.Count; i++)
                {
                    mainWindow.GeoObjects[i].IsActive = true;
                }
            }
            else
            {
                for (int i = 0; i < mainWindow.GeoObjects.Count; i++)
                {
                    mainWindow.GeoObjects[i].IsActive = false;
                }
            }
            mainWindow.Refresh();
        }

        private SimpleCADControl.GeoObjects.Polygon genCellPolyFromCellContourList(SimpleCADControl.Vector2D[] cellContourArray)
        {
            SimpleCADControl.GeoObjects.Polygon poly = null;
            try
            {
                poly = new SimpleCADControl.GeoObjects.Polygon(cellContourArray);
                poly.Parent = mainWindow;
                poly.IsActive = false;
                poly.DrawingColor = Color.Green;
                poly.DrawingWidth = 2;
                poly.Layer = 1;
            }
            catch { return poly; }
            return poly;
        }
        private SimpleCADControl.GeoObjects.Polygon genCellPolyFromCellContourList(SimpleCADControl.Vector2D[] cellContourArray, Color color)
        {
            SimpleCADControl.GeoObjects.Polygon poly = null;
            try
            {
                poly = new SimpleCADControl.GeoObjects.Polygon(cellContourArray);
                poly.Parent = mainWindow;
                poly.IsActive = false;
                poly.DrawingColor = color;
                poly.DrawingWidth = 2;
                poly.Layer = 1;
            }
            catch { return poly; }
            return poly;
        }
        private SimpleCADControl.GeoObjects.Polygon genCorePolyFromCoreContourList(SimpleCADControl.Vector2D[] coreContourArray)
        {
            SimpleCADControl.GeoObjects.Polygon poly = null;

            poly = new SimpleCADControl.GeoObjects.Polygon(coreContourArray);
            poly.Parent = mainWindow;
            poly.IsActive = false;
            poly.DrawingColor = Color.SkyBlue;
            poly.DrawingWidth = 2;
            poly.Layer = 2;

            return poly;
        }
        private SimpleCADControl.GeoObjects.Polygon genCorePolyFromCoreContourList(SimpleCADControl.Vector2D[] coreContourArray, Color color)
        {
            SimpleCADControl.GeoObjects.Polygon poly = null;

            poly = new SimpleCADControl.GeoObjects.Polygon(coreContourArray);
            poly.Parent = mainWindow;
            poly.IsActive = false;
            poly.DrawingColor = color;
            poly.DrawingWidth = 2;
            poly.Layer = 2;

            return poly;
        }
        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < flowLayoutPanel_Templates.Controls.Count; i++)
            {
                if (((CustomControls.HB_Template_Control)(flowLayoutPanel_Templates.Controls[i])).clicked == true)
                {
                    flowLayoutPanel_Templates.Controls.RemoveAt(i);
                    TemplateList.RemoveAt(i);
                    flowLayoutPanel_Templates.Show();
                }
            }
            for (int i = 0; i < flowLayoutPanel_CellSegTemplates.Controls.Count; i++)
            {
                if (((CustomControls.HB_Template_Control)(flowLayoutPanel_CellSegTemplates.Controls[i])).clicked == true)
                {
                    flowLayoutPanel_CellSegTemplates.Controls.RemoveAt(i);
                    TemplateCellSegList.RemoveAt(i);
                    flowLayoutPanel_CellSegTemplates.Show();
                }
            }
        }
        private void button_LoadTemplate_Click(object sender, EventArgs e)
        {
            ImportTemplateImage();
        }
        private List<cellData> SyncHalObjFromGeoObj(HWindow window, SimpleCADControl.CADControl mainWindow, List<cellData> cells, int minCellArea)
        {
            HObject newCellRegion, newCellsRegion;
            HObject newCoresRegion;
            HTuple rows, cols;

            List<cellData> newCellDataList = new List<cellData>();
            List<cellCoreData> newCellCores = new List<cellCoreData>();

            HOperatorSet.GenEmptyObj(out newCellsRegion);
            HOperatorSet.GenEmptyObj(out newCoresRegion);
            HOperatorSet.ClearWindow(window);

            int counter = 0;

            HObject img_Saturation_HAL;

            TImage img_Saturation = imageWorker.calcRGBImgSaturation(new TImage(mainWindow.Image));

            HalconDotNet.HOperatorSet.GenImageInterleaved(out img_Saturation_HAL, img_Saturation.firstPixel, "bgr",
                                                          img_Saturation.Width, img_Saturation.Height, 0, "byte",
                                                          0, 0, 0, 0, -1, 0);

            List<GeoObject> SAVGeoObjects = new List<GeoObject>(mainWindow.GeoObjects);
            List<GeoObject> coreObjects = new List<GeoObject>();
            List<GeoObject> cellObjects = new List<GeoObject>();

            try
            {
                //Kerne und Zellen in seperate Listen auslagern um die nachfolgende Schleife zu beschleunigen
                for (int i = 0; i < mainWindow.GeoObjects.Count; i++)
                {
                    if (mainWindow.GeoObjects[i].Layer == 2)
                    {
                        coreObjects.Add(mainWindow.GeoObjects[i]);
                    }
                    else if ((mainWindow.GeoObjects[i].Layer == 1) ||
                             (mainWindow.GeoObjects[i].Layer == 4) ||
                             (mainWindow.GeoObjects[i].Layer == 5))
                    {
                        cellObjects.Add(mainWindow.GeoObjects[i]);
                    }
                }
                int numberNotMatched = 0;
                bool matched = false;
                //Alle Datensätze aus dem Dictionary löschen, dessen Geobjekte keinen Match mehr mit einem GeoObjekt
                //im Fenster haben. In diesem Fall wurde das GeoObjekt geschnitten und 2 neue GeoObjekte sind entstanden
                for (int i = 0; i < cellDataPolyCollection.Count; i++)
                {
                    matched = false;
                    for (int j = 0; j < cellObjects.Count; j++)
                    {
                        if (cellDataPolyCollection.Values.ElementAt(i) == cellObjects[j])
                        {
                            matched = true;
                            break;
                        }
                    }
                    //Falls zu einem Polygon in einem Dictionaryeintrag kein passendes Polygon im Fenster gefunden wurde
                    //entsprechenden Datensatz aus dem Dictionary und dem Datagrid löschen
                    if (matched == false)
                    {
                        int ind = (int)cellDataPolyCollection.Keys.ElementAt(i).Cells[0].Value - 1;
                        if (dataGridView_CellStatistics.Rows.Count > 0)
                            dataGridView_CellStatistics.Rows.RemoveAt(ind - numberNotMatched);
                        cellDataPolyCollection.Remove(cellDataPolyCollection.Keys.ElementAt(i));
                        i--;
                        numberNotMatched++;
                    }
                }
                for (int i = 0; i < cellObjects.Count; i++)
                {
                    cellObjects[i].Label = Convert.ToString(i + 1);
                    //Zellkonturen syncronisieren falls vorhanden
                    counter++;
                    //Zellinformationen neu berechnen lassen
                    //->Prüfen ob vorhandene Kerne zu diesem Polygon gehören
                    //->Zellstatistiken neu berechnen
                    HOperatorSet.TupleGenConst(cellObjects[i].EditPoints.Count, 0, out rows);
                    HOperatorSet.TupleGenConst(cellObjects[i].EditPoints.Count, 0, out cols);

                    for (int k = 0; k < cellObjects[i].EditPoints.Count; k++)
                    {
                        rows[k] = cellObjects[i].EditPoints[k].Y;
                        cols[k] = cellObjects[i].EditPoints[k].X;
                    }
                    //Halcon Region aus Polygon-Stützpunkten erzeugen
                    HOperatorSet.GenRegionPolygonFilled(out newCellRegion, rows, cols);

                    cellData newCell = new cellData();
                    newCell.cellRegion = newCellRegion;
                    newCell.nr = counter;
                    //Prüfen welche Kerne innerhalb des aktuellen Polygons liegen und der neuen Zelle zuweisen
                    //Dazu jeden Kern in eine Halcon-Region umwandeln und einen Schnitttest mit der Zellregion durchführen
                    //newCell.CoreInfo = CoresInsidePoly(newCellRegion, mainWindow.GeoObjects);
                    newCell.CoreInfo = cellDataFromGeoObjects.CoresInsidePoly(newCellRegion, coreObjects);
                    //Neuen Zellstatistikdatensatz hinzufügen
                    newCell = calcCellStatistics(newCell, checkBox_CalcSaturation.Checked, img_Saturation_HAL);
                    //Zellvitalität/Status zuweisen
                    if (cellObjects[i].Layer == 1)
                    {
                        newCell.isAlive = true;

                        //Da sich die Zellmerkmale bei einer Bearbeitung ändern könnte, wird die Zellvitalität
                        //hier noch mal neu berechnet
                        newCell = cellAnalyser.analyseCellVitality(newCell, comboBox_feature1.Text, comboBox_feature2.Text, comboBox_feature3.Text,
                                                                   Convert.ToDouble(textBox_feature1_min.Text), Convert.ToDouble(textBox_feature1_max.Text),
                                                                   Convert.ToDouble(textBox_feature2_min.Text), Convert.ToDouble(textBox_feature2_max.Text),
                                                                   Convert.ToDouble(textBox_feature3_min.Text), Convert.ToDouble(textBox_feature3_max.Text));
                        //GGF. Layer neu setzten wenn sich der Vitalitätsstatus einer Zelle geändert hat
                        if (newCell.isAlive == true)
                        {
                            if (newCell.wasBarbelCell == true)
                                cellObjects[i].Layer = 5;
                            else
                                cellObjects[i].Layer = 1;
                        }
                        else
                        {
                            if (newCell.wasBarbelCell == true)
                                cellObjects[i].Layer = 5;
                            else
                                cellObjects[i].Layer = 4;
                        }
                    }
                    if (cellObjects[i].Layer == 4)
                    {
                        newCell.isAlive = false;
                    }
                    if (cellObjects[i].Layer == 5)
                    {
                        newCell.wasBarbelCell = true;

                        //Da sich die Zellmerkmale bei einer Bearbeitung ändern könnte, wird die Zellvitalität
                        //hier noch mal neu berechnet
                        newCell = cellAnalyser.analyseCellVitality(newCell, comboBox_feature1.Text, comboBox_feature2.Text, comboBox_feature3.Text,
                                                                   Convert.ToDouble(textBox_feature1_min.Text), Convert.ToDouble(textBox_feature1_max.Text),
                                                                   Convert.ToDouble(textBox_feature2_min.Text), Convert.ToDouble(textBox_feature2_max.Text),
                                                                   Convert.ToDouble(textBox_feature3_min.Text), Convert.ToDouble(textBox_feature3_max.Text));
                        //GGF. Layer neu setzten wenn sich der Vitalitätsstatus einer Zelle geändert hat
                        if (newCell.isAlive == true)
                        {
                            if (newCell.wasBarbelCell == true)
                                cellObjects[i].Layer = 5;
                            else
                                cellObjects[i].Layer = 1;
                        }
                        else
                        {
                            if (newCell.wasBarbelCell == true)
                                cellObjects[i].Layer = 5;
                            else
                                cellObjects[i].Layer = 4;
                        }
                    }
                    newCellDataList.Add(newCell);
                    //DataGrid-Zellen für Zellstatistiken neu zuweisen, da sich die Zelleigenschaften durch ein mögliches Editieren
                    //geändert haben können
                    bool polygonMatched = false;
                    foreach (var item in cellDataPolyCollection)
                    {
                        //Aktuell gewähltes Polygon in der for-Schleife auch in Dictionary raussuchen
                        if (item.Value == cellObjects[i] as Polygon)
                        {
                            item.Key.Cells[0].Value = i + 1;
                            item.Key.Cells[1].Value = newCell.statistics.cellArea;
                            item.Key.Cells[2].Value = newCell.statistics.coreCount;
                            item.Key.Cells[3].Value = Math.Round(newCell.statistics.circularity, 2);
                            item.Key.Cells[4].Value = Math.Round(newCell.statistics.saturation, 2);
                            item.Key.Cells[5].Value = Math.Round(newCell.statistics.cellForm, 2);
                            if ((cellObjects[i].Layer == 1) || (cellObjects[i].Layer == 5))
                                item.Key.Cells[6].Value = "alive";
                            if (cellObjects[i].Layer == 4)
                                item.Key.Cells[6].Value = "dead";
                            polygonMatched = true;
                            break;
                        }
                    }
                    //Wenn kein Polygon aus dem Dictionary zu dem ausgewählten Polygon des Bildfensters passt muss es sich 
                    //um ein neu erstelltes Polygon handelt dass nun in das Dictionary und das Datagrid aufgenommen werden muss
                    if (polygonMatched == false)
                    {
                        DataGridViewRow newRow = new DataGridViewRow();

                        //Nur Polygone die Zellen darstellen sollen im Dictionary den Zelldaten in cells zugeordnet werden. 
                        //Zelllöcher die auch Polygone im CAD-Control vorhanden sind sollen natürlich nicht in die Zellstatistik als
                        //eigenständige Zellen einfließen, deswegen hier die Abfrage nach dem Layer
                        if ((cellObjects[i].Layer == 1) ||
                           (cellObjects[i].Layer == 4) ||
                           (cellObjects[i].Layer == 5))
                        {
                            cellPolyCollection.Add(cellObjects[i] as Polygon, newCell);
                            if (checkBox_showCellNumber.Checked == true)
                            {
                                (cellObjects[i] as Polygon).Label = Convert.ToString(newCell.nr);
                                (cellObjects[i] as Polygon).ShowLabel = true;
                            }
                        }
                        if ((cellObjects[i].Layer == 1) || (cellObjects[i].Layer == 5))
                            newRow.CreateCells(dataGridView_CellStatistics, newCell.nr, newCell.statistics.cellArea, newCell.statistics.coreCount, Math.Round(newCell.statistics.circularity, 2), Math.Round(newCell.statistics.saturationDeviation, 2), Math.Round(newCell.statistics.cellForm, 2), "alive", (cellObjects[i] as Polygon).Info);
                        if (cellObjects[i].Layer == 4)
                            newRow.CreateCells(dataGridView_CellStatistics, newCell.nr, newCell.statistics.cellArea, newCell.statistics.coreCount, Math.Round(newCell.statistics.circularity, 2), Math.Round(newCell.statistics.saturationDeviation, 2), Math.Round(newCell.statistics.cellForm, 2), "dead", (cellObjects[i] as Polygon).Info);
                        newRow.ReadOnly = false;
                        cellDataPolyCollection.Add(newRow, cellObjects[i] as Polygon);
                        dataGridView_CellStatistics.Invoke(Delegate.CreateDelegate(typeof(ViewInDataGridDelegate), this, "ViewInDataGrid"), newRow);
                    }
                }
                //Zellen mit einer Fläche kleiner der eingestellten Mindestfläche werden gelöscht
                for (int j = 0; j < cellDataPolyCollection.Count; j++)
                {
                    //Wenn die Zellfläche < 200 -> aus DataGrid und Zellliste löschen
                    if (Convert.ToInt32(cellDataPolyCollection.Keys.ElementAt(j).Cells[1].Value) < minCellArea)
                    {
                        cellPolyCollection.Remove(cellDataPolyCollection.Values.ElementAt(j));
                        mainWindow.GeoObjects.Remove(cellDataPolyCollection.Values.ElementAt(j));
                        dataGridView_CellStatistics.Rows.Remove(cellDataPolyCollection.Keys.ElementAt(j));
                        cellDataPolyCollection.Remove(cellDataPolyCollection.Keys.ElementAt(j));
                        j--;
                    }
                }
                for (int j = 0; j < newCellDataList.Count; j++)
                {
                    if (newCellDataList[j].statistics.cellArea < minCellArea)
                    {
                        newCellDataList.RemoveAt(j);
                        j--;
                    }
                }
                for (int j = 0; j < newCellDataList.Count; j++)
                {
                    newCellDataList[j].nr = j + 1;
                }
                //ZellObjekt-Liste neu erstellen da Objekte möglicherweise entfernt wurden
                coreObjects.Clear();
                cellObjects.Clear();
                for (int i = 0; i < mainWindow.GeoObjects.Count; i++)
                {
                    if (mainWindow.GeoObjects[i].Layer == 2)
                    {
                        coreObjects.Add(mainWindow.GeoObjects[i]);
                    }
                    else if ((mainWindow.GeoObjects[i].Layer == 1) ||
                            (mainWindow.GeoObjects[i].Layer == 4) ||
                            (mainWindow.GeoObjects[i].Layer == 5))
                    {
                        cellObjects.Add(mainWindow.GeoObjects[i]);
                    }
                }
                //Nummerierung der Zellen im DataGrid anpassen falls vorher Zellen gelöscht wurden
                for (int i = 0; i < cellObjects.Count; i++)
                {
                    cellObjects[i].Label = Convert.ToString(i + 1);
                    foreach (var item in cellDataPolyCollection)
                    {
                        //Aktuell gewähltes Polygon in der for-Schleife auch in Dictionary raussuchen
                        if (item.Value == cellObjects[i] as Polygon)
                        {
                            item.Key.Cells[0].Value = i + 1;
                            break;
                        }
                    }
                }
                update();
                //Im DataGrid an die Stelle der selektierten Zelle scrollen
                foreach (var item in cellDataPolyCollection)
                {
                    if (item.Value == mainWindow.SelectedObject as Polygon)
                    {
                        dataGridView_CellStatistics.Rows[item.Key.Index].Selected = true;
                        dataGridView_CellStatistics.FirstDisplayedScrollingRowIndex = dataGridView_CellStatistics.SelectedRows[0].Index;
                        break;
                    }
                }
                return newCellDataList;
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("Fehler beim Syncronisieren " + ex.Message);
                return newCellDataList;
            }
        }

        private void toolStripButton_SyncHalObjWithGeoObj_Click(object sender, EventArgs e)
        {
            try
            {
                this.Cursor = busyCursor;

                cells = SyncHalObjFromGeoObj(window, mainWindow, cells, singleSlider_Area.Value);

                contourList.Clear();
                coresContourList.Clear();

                //CAD-Konturen-Listen für Zellen und Zellkerne aktualisieren für Reset-Funktion
                for (int i = 0; i < mainWindow.GeoObjects.Count; i++)
                {
                    if (mainWindow.GeoObjects[i].Layer == 1)
                    {
                        contourList.Add(mainWindow.GeoObjects[i].EditPoints.ToArray());
                    }
                    else if (mainWindow.GeoObjects[i].Layer == 2)
                    {
                        coresContourList.Add(mainWindow.GeoObjects[i].EditPoints.ToArray());
                    }
                }

                int totalCellCount, aliveCellCount, deadCellCount;
                double meanSaturation, averageCellArea, cellDensity;
                String averageCellAreaUnit, cellDensityUnit;

                HTuple pointer, type, width, height;
                HOperatorSet.GetImagePointer1(mainImg, out pointer, out type, out width, out height);

                cellAnalyser.getCellAnalysisResults(cells, mainWindow.GeoObjects, mainWindow.CalibrationFactor, width, height,
                                                    out totalCellCount, out aliveCellCount, out deadCellCount, out meanSaturation,
                                                    out averageCellArea, out averageCellAreaUnit, out cellDensity, out cellDensityUnit);

                //Durchschnittliche Zellfläche anzeigen lassen
                this.Invoke((MethodInvoker)delegate()
                {
                    textBox_AverageCellArea.Text = Convert.ToString(Math.Round(averageCellArea, 1));
                    textBox_AverageCellAreaUnit.Text = averageCellAreaUnit;
                });
                //Durchschnittliche Farbsättigung der Zellen anzeigen lassen
                this.Invoke((MethodInvoker)delegate()
                {
                    textBox_MeanCellSaturation.Text = Convert.ToString(Math.Round(meanSaturation, 2));
                });
                //Gesamtzellanzahl, Anzahl lebender und toter Zellen sowie die Vitalität anzeigen lassen
                this.Invoke((MethodInvoker)delegate()
                {
                    textBox_TotalCellCount.Text = Convert.ToString(totalCellCount);
                });
                this.Invoke((MethodInvoker)delegate()
                {
                    textBox_CellsAlive.Text = Convert.ToString(aliveCellCount);
                });
                this.Invoke((MethodInvoker)delegate()
                {
                    textBox_CellsDead.Text = Convert.ToString(deadCellCount);
                });
                this.Invoke((MethodInvoker)delegate()
                {
                    textBox_Viability.Text = Convert.ToString(Math.Round((((double)aliveCellCount / totalCellCount) * 100),2)) + " %";
                });
                //----------------------------------------------------------------------------------
                //Gesamtfläche des Probenausschnittes bestimmen (in m^2):
                //----------------------------------------------------------------------------------
                this.Invoke((MethodInvoker)delegate()
                {
                    textBox_CellDensity.Text = Convert.ToString(Math.Round(cellDensity, 1));
                    textBox_CellDensityUnit.Text = cellDensityUnit;
                });

                this.Cursor = Cursors.Default;

                mainWindow.Focus();
                mainWindow.Invalidate(true);
            }
            catch { this.Cursor = Cursors.Default; }
        }

        private void update()
        {
            //Das true bewirkt Neuzeichnen der Kind-Elemente
            this.Invoke((MethodInvoker)delegate()
            {
                this.Invalidate(true);
            });
        }

        private void checkBox_PropertyGrid_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox_PropertyGrid.Checked == true)
                mainWindow.PropertyGridVisible = true;
            else
                mainWindow.PropertyGridVisible = false;
        }
        private void runAlgo(Object par)
        {
            lock (lockvar)
            {
                HObject cellRegions = null;
                HObject holesRegions = null;
                //HObject mainImg;
                Object[] pars = (Object[])par;

                timer.Reset();
                timer.Start();
                //-------------------------------------------------------------------------------------------------------
                //-------------------------------------------------------------------------------------------------------
                //Wenn gewünscht Schritt 0: Bildvorverarbeitung -> Pixel mit einem erhöhten Farbanteil einer bestimmten
                //Farbe durch die Farbe ersetzen, die am häufigsten im Bild vorkommt (Hintergrundfarbe)
                //-------------------------------------------------------------------------------------------------------
                //-------------------------------------------------------------------------------------------------------
                try
                {
                    if (Convert.ToBoolean(pars[19]) == true)
                    {
                        SBBitmap.WarpBitmap orgImg = new SBBitmap.WarpBitmap(mainWindow.Image);
                        SBBitmap.WarpBitmap newImg = ImagePreprocessing.ImagePreprocessing.Preprocess(orgImg, (ImagePreprocessing.ImagePreprocessing._Color)pars[21], Convert.ToDouble(pars[20]));

                        mainWindow.ImageBMP = newImg.Image;
                        FileStream fs = new FileStream(Application.StartupPath + "\\CellImgPreProcessed.bmp", FileMode.Create, FileAccess.Write);
                        ((Bitmap)newImg.Image.Clone()).Save(fs, ImageFormat.Bmp);
                        fs.Flush();
                        fs.Close();
                        fs.Dispose();
                        HOperatorSet.ReadImage(out mainImg, Application.StartupPath + "\\CellImgPreProcessed.bmp");
                    }
                    else
                    {
                        HOperatorSet.ReadImage(out mainImg, mainWindow.Image);
                    }
                    //HOperatorSet.ReadImage(out mainImg, Application.StartupPath + "\\CellImgPreProcessed.bmp");
                    //-------------------------------------------------------------------------------------------------------
                    //-------------------------------------------------------------------------------------------------------
                    //SCHRITT 1: SEGMENTIERUNG DER ZELLEN
                    //-------------------------------------------------------------------------------------------------------
                    //-------------------------------------------------------------------------------------------------------        
                    HOperatorSet.SetSystem("neighborhood", 4);
                    if (pars[0].ToString() == "Threshold - Foreground")
                    {
                        if (checkBox_EditRGBSimultan.Checked == true)
                        {
                            if (checkBox_EditRGBHolesSimultan.Checked == true)
                            {
                                cellRegions = cellSegmentation_Threshold.segmentation(mainImg,
                                                              doubleSlider_ThreshRGB.LowerValue,
                                                              doubleSlider_ThreshRGB.UpperValue,
                                                              doubleSlider_ThreshRGB.LowerValue,
                                                              doubleSlider_ThreshRGB.UpperValue,
                                                              doubleSlider_ThreshRGB.LowerValue,
                                                              doubleSlider_ThreshRGB.UpperValue,
                                                              singleSlider_Area.Value,
                                                              doubleSlider_HolesThreshRGB.LowerValue,
                                                              doubleSlider_HolesThreshRGB.UpperValue,
                                                              doubleSlider_HolesThreshRGB.LowerValue,
                                                              doubleSlider_HolesThreshRGB.UpperValue,
                                                              doubleSlider_HolesThreshRGB.LowerValue,
                                                              doubleSlider_HolesThreshRGB.UpperValue,
                                                              checkBox_FindCellHoles.Checked, window,
                                                              out holesRegions);
                            }
                            else
                            {
                                cellRegions = cellSegmentation_Threshold.segmentation(mainImg,
                                                              doubleSlider_ThreshRGB.LowerValue,
                                                              doubleSlider_ThreshRGB.UpperValue,
                                                              doubleSlider_ThreshRGB.LowerValue,
                                                              doubleSlider_ThreshRGB.UpperValue,
                                                              doubleSlider_ThreshRGB.LowerValue,
                                                              doubleSlider_ThreshRGB.UpperValue,
                                                              singleSlider_Area.Value,
                                                              doubleSlider_HolesThreshR.LowerValue,
                                                              doubleSlider_HolesThreshR.UpperValue,
                                                              doubleSlider_HolesThreshG.LowerValue,
                                                              doubleSlider_HolesThreshG.UpperValue,
                                                              doubleSlider_HolesThreshB.LowerValue,
                                                              doubleSlider_HolesThreshB.UpperValue,
                                                              checkBox_FindCellHoles.Checked, window,
                                                              out holesRegions);
                            }
                        }
                        else
                        {
                            if (checkBox_EditRGBHolesSimultan.Checked == true)
                            {
                                cellRegions = cellSegmentation_Threshold.segmentation(mainImg,
                                                                                      doubleSlider_ThreshR.LowerValue,
                                                                                      doubleSlider_ThreshR.UpperValue,
                                                                                      doubleSlider_ThreshG.LowerValue,
                                                                                      doubleSlider_ThreshG.UpperValue,
                                                                                      doubleSlider_ThreshB.LowerValue,
                                                                                      doubleSlider_ThreshB.UpperValue,
                                                                                      singleSlider_Area.Value,
                                                                                      doubleSlider_HolesThreshRGB.LowerValue,
                                                                                      doubleSlider_HolesThreshRGB.UpperValue,
                                                                                      doubleSlider_HolesThreshRGB.LowerValue,
                                                                                      doubleSlider_HolesThreshRGB.UpperValue,
                                                                                      doubleSlider_HolesThreshRGB.LowerValue,
                                                                                      doubleSlider_HolesThreshRGB.UpperValue,
                                                                                      checkBox_FindCellHoles.Checked, window,
                                                                                      out holesRegions);
                            }
                            else
                            {
                                cellRegions = cellSegmentation_Threshold.segmentation(mainImg,
                                                                                      doubleSlider_ThreshR.LowerValue,
                                                                                      doubleSlider_ThreshR.UpperValue,
                                                                                      doubleSlider_ThreshG.LowerValue,
                                                                                      doubleSlider_ThreshG.UpperValue,
                                                                                      doubleSlider_ThreshB.LowerValue,
                                                                                      doubleSlider_ThreshB.UpperValue,
                                                                                      singleSlider_Area.Value,
                                                                                      doubleSlider_HolesThreshR.LowerValue,
                                                                                      doubleSlider_HolesThreshR.UpperValue,
                                                                                      doubleSlider_HolesThreshG.LowerValue,
                                                                                      doubleSlider_HolesThreshG.UpperValue,
                                                                                      doubleSlider_HolesThreshB.LowerValue,
                                                                                      doubleSlider_HolesThreshB.UpperValue,
                                                                                      checkBox_FindCellHoles.Checked, window,
                                                                                      out holesRegions);
                            }
                        }
                    }
                    else if (pars[0].ToString() == "Threshold - Background")
                    {
                        //Automatisch die Schwellen für den Threshold des Hintergrundes berechnen lassen.
                        //Dazu wird im Histogram des G-Kanals aus dem Originalbild ein Grauwertintervall von 15 Pixel breite
                        //über das Histogramm verfahren und die Indizes gespeichert, die die meisten Pixel einschließen
                        //Auf diese Weise werden die Schwellen optimal zur Segmentierung des Hintergrundes gesetzt da wir davon ausgehen
                        //das die Hintergrundfläche den größten homogenen Farbanteil im Bild ausmacht
                        int thresh_lower = 0;
                        int thresh_upper = 0;
                        backgroundseg_Threshold.threshFromHisto(mainImg, out thresh_lower, out thresh_upper);

                        pars[2] = thresh_lower;
                        pars[3] = thresh_upper;

                        cellRegions = backgroundseg_Threshold.segmentation(mainImg,
                                                                           Convert.ToInt32(pars[2]),
                                                                           Convert.ToInt32(pars[3]),
                                                                           Convert.ToInt32(pars[4]),
                                                                           Convert.ToInt32(pars[5]),
                                                                           out holesRegions);
                        if (checkBox_HalconDebugMode.Checked == true)
                        {
                            HOperatorSet.SetPart(window, 0, 0, -1, -1);
                            HOperatorSet.DispObj(mainImg, window);
                            HOperatorSet.SetPart(window, 0, 0, -1, -1);
                            HOperatorSet.DispObj(mainImg, window);
                            HOperatorSet.SetColor(window, "green");
                            HOperatorSet.DispObj(cellRegions, window);
                            HOperatorSet.SetColor(window, "red");
                            HOperatorSet.DispObj(holesRegions, window);
                        }
                    }
                    else if (pars[0].ToString() == "Histogram Backprojection")
                    {
                        HObject SourceImageOnlyCells_HAL = null;
                        TImage SourceImageOnlyCells;

                        SourceImage = new TImage(mainWindow.Image);
                        SourceImageOnlyCells = new TImage(SourceImage.Width, SourceImage.Height, SourceImage.Pixelformat);

                        if (TemplateCellSegList.Count > 1)
                        {
                            backprojection.multi_hist_backprojection(SourceImage, TemplateCellSegList, SourceImageOnlyCells, Convert.ToInt32(pars[6]));
                        }
                        else if (TemplateCellSegList.Count == 1)
                        {
                            backprojection.hist_backprojection(SourceImage, TemplateCellSegList[0], SourceImageOnlyCells, Convert.ToInt32(pars[6]));
                        }
                        else if (TemplateCellSegList.Count == 0)
                        {
                            this.Invoke((MethodInvoker)delegate()
                            {
                                this.Cursor = Cursors.Default;
                            });
                            inProcess = false;
                            return;
                        }

                        cadControlWin_cellCores.ImageBMP = (Bitmap)SourceImageOnlyCells.Image.Clone();

                        if (SourceImageOnlyCells_HAL != null)
                            SourceImageOnlyCells_HAL.Dispose();

                        //Durch diese Zuweisung scheint die gelockte Bitmap wieder ungelocked zu werden und
                        //nur so erfolgt die Umwandlung in ein Halconobjekt problemlos
                        Bitmap dummy = SourceImageOnlyCells.Image;
                        dummy = null;

                        HalconDotNet.HOperatorSet.GenImageInterleaved(out SourceImageOnlyCells_HAL, SourceImageOnlyCells.firstPixel, "bgr",
                                                      SourceImageOnlyCells.Width, SourceImageOnlyCells.Height, 0, "byte",
                                                      0, 0, 0, 0, -1, 0);

                        //Bildnachbearbeitung -> bin-Thresold zur Zellsegmentierung, Closing zum Schließen kleinerer
                        //Löcher und Extraktion der Zellen mit Merkmal "Fläche" > 350Pix
                        //und Rückgabe der selektierten Zellbereiche als Regionen
                        cellRegions = HalconFunctions.getCellsAsRegions(SourceImageOnlyCells_HAL, Convert.ToInt32(pars[4]));
                    }
                    else
                    {
                        inProcess = false;
                        this.Invoke((MethodInvoker)delegate()
                        {
                            this.Cursor = Cursors.Default;
                        });
                        return;
                    }

                }
                catch (System.Exception ex)
                {
                    MessageBox.Show("Fehler in Schritt 1 " + ex.Message);
                    inProcess = false;
                    this.Invoke((MethodInvoker)delegate()
                    {
                        this.Cursor = Cursors.Default;
                    });
                    return;
                }
                //-------------------------------------------------------------------------------------------------------
                //-------------------------------------------------------------------------------------------------------
                //SCHRITT 2: KLASSIFIKATION DER ZELLEN ALS ZELLCLUSTER BZW. EINZELZELLEN
                //-------------------------------------------------------------------------------------------------------
                //-------------------------------------------------------------------------------------------------------
                if (cellRegions != null)
                {
                    try
                    {
                        ClusterClassification.iterativeErosionClassifier(cellRegions, out cells);
                        //-------------------------------------------------------------------------------------------------------
                        //-------------------------------------------------------------------------------------------------------
                        //Zwischenschritt: Zelllöcher den entsprechenden Zellen zuordnen
                        //-------------------------------------------------------------------------------------------------------
                        //-------------------------------------------------------------------------------------------------------
                        //Wenn keine Zellen vorhanden sind den Algorithmus beenden
                        if (cells.Count == 0)
                        {
                            setDefaultVarAlgo();
                            return;
                        }
                        //-------------------------------------------------------------------------------------------------------
                        //Wenn Hantelzellen gesucht und aufgespalten werden sollen hier durchführen
                        //-------------------------------------------------------------------------------------------------------
                        if (Convert.ToBoolean(pars[18]) == true)
                        {
                            cells = BarbellCellDivision.division_barbell_cells(cells, Convert.ToInt32(pars[22]), window);

                            //Zellnummern neu erstellen, da diese durch das Löschen und Hinzufügen von Zellen durcheinandergekommen sein können
                            for (int i = 0; i < cells.Count; i++)
                            {
                                cells[i].nr = i + 1;
                            }
                        }
                        if (Convert.ToBoolean(pars[15]) == true)
                        {
                            //Alle Cluster in eine Liste zusammenstellen
                            List<cellData> cellClusters = new List<cellData>();
                            for (int i = 0; i < cells.Count; i++)
                            {
                                if (cells[i].isCluster == true)
                                {
                                    cellClusters.Add(cells[i]);
                                }
                            }
                            //Nach der Klassifizierung nun die kontextbasierte Erosion durchlaufen lassen um Verengungen in den Clustern
                            //aufzutrennen und somit die nachfolgende Zelltrennung via Zellkerne zu beschleunigen.
                            cellClusters = contextBasedErosion_HAL.startCBE(mainImg, cellClusters, window);
                            //Zellcluster aus Zellliste entfernen und neue Zellcluster einfügen
                            for (int i = 0; i < cells.Count; i++)
                            {
                                if (cells[i].isCluster == true)
                                {
                                    cells.RemoveAt(i);
                                    i--;
                                }
                            }
                            for (int i = 0; i < cellClusters.Count; i++)
                            {
                                cells.Add(cellClusters[i]);
                            }
                            //Zellnummern neu erstellen, da diese durch das Löschen und Hinzufügen von Zellen durcheinandergekommen sein können
                            for (int i = 0; i < cells.Count; i++)
                            {
                                cells[i].nr = i + 1;
                            }
                        }
                        cells = HalconFunctions.assignCellHolesToCellDataList(cells, holesRegions);
                    }
                    catch (System.Exception ex)
                    {
                        MessageBox.Show("Fehler in Schritt 2" + ex.Message);
                        inProcess = false;

                        this.Invoke((MethodInvoker)delegate()
                        {
                            this.Cursor = Cursors.Default;
                        });
                        return;
                    }
                    //DCPs anzeigen falls gewünscht
                    if (checkBox_dynActualisationDCPs.Checked == true)
                    {
                        List<SimpleCADControl.Vector2D[]> DCPArrList = new List<SimpleCADControl.Vector2D[]>();

                        try
                        {
                            for (int i = 0; i < cells.Count; i++)
                            {
                                FindSpecialContourPoint dcps = null;

                                dcps = new FindSpecialContourPoint(cells[i].cellRegion, (int)(pars[1]));
                                List<DCP.DoublePoint> DCPList;
                                //DCPs finden
                                DCPList = dcps.FindAllMaxima(Direction.Left, Direction.Right, Direction.Up, Direction.Down);

                                List<SimpleCADControl.Vector2D> arr = new List<SimpleCADControl.Vector2D>();
                                foreach (DCP.DoublePoint point in DCPList)
                                {
                                    arr.Add(new SimpleCADControl.Vector2D(point.X, point.Y));
                                }
                                DCPArrList.Add(arr.ToArray());
                                for (int j = 0; j < DCPArrList[DCPArrList.Count - 1].Length; j++)
                                {
                                    Circle circle = new Circle(DCPArrList[DCPArrList.Count - 1][j], 5);
                                    circle.Parent = mainWindow;
                                    circle.DrawingColor = Color.Blue;
                                    circle.DrawingWidth = 5;
                                    circle.Layer = 3;
                                    mainWindow.GeoObjects.Add(circle);
                                    update();
                                }
                            }
                        }
                        catch
                        {
                            inProcess = false;

                            this.Invoke((MethodInvoker)delegate()
                            {
                                this.Cursor = Cursors.Default;
                            });
                            return;
                        }
                    }
                    statusBar_Steps.Value = statusBar_Steps.Breakpoints[0].ProgressPosition;
                }
                else
                    toolStripButton_Stop_Click(this, new EventArgs());

                //-------------------------------------------------------------------------------------------------------
                //-------------------------------------------------------------------------------------------------------
                //SCHRITT 3: DETEKTION DER ZELLKERNREGIONEN MITTELS HISTOGRAM BACKPROJECTION
                //-------------------------------------------------------------------------------------------------------
                //-------------------------------------------------------------------------------------------------------
                if ((checkBox_cellsegmentation.Checked == true) && (checkBox_cellcoredetection.Checked == true))
                {
                    //Quellbild für den-HB-Algorithmus erstellen, auf Basis der segmentierten Zellbereiche aus Schritt 1:
                    //geladenes Bild in Halcon Objekt umwandeln
                    HObject cellImg_HAL, unionCellRegion;
                    TImage HBCoreImage = null;
                    HOperatorSet.Union1(cellRegions, out unionCellRegion);
                    HOperatorSet.ReduceDomain(mainImg, unionCellRegion, out cellImg_HAL);
                    try
                    {
                        if (SourceImage != null)
                        {
                            SourceImage.Image.Dispose();
                        }
                        HOperatorSet.WriteImage(cellImg_HAL, "bmp", 0, Application.StartupPath + "\\CellImg.bmp");

                        //SourceImage = new TImage(Application.StartupPath + "\\CellImg.bmp");
                        //HBCoreImage = new TImage(SourceImage.Width, SourceImage.Height, SourceImage.Pixelformat);

                        //Erst mal über get-Pixel Methoden Grauwerte aus HAL-Bild rausziehen und in TImage Bild schreiben aber sollte eigentlich über Pointer schneller gehen
                        HObject imgR, imgG, imgB;
                        HTuple pointer, typ, imgWidth, imgHeight, valR, valG, valB, regionRows, regionCols;
                        HOperatorSet.GetImagePointer1(cellImg_HAL, out pointer, out typ, out imgWidth, out imgHeight);
                        HOperatorSet.Decompose3(cellImg_HAL, out imgR, out imgG, out imgB);
                        //Pixel aus dem Halconbild in das TImage schreiben
                        SourceImage = new TImage(imgWidth, imgHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                        HOperatorSet.GetRegionPoints(unionCellRegion, out regionRows, out regionCols);
                        for (int i = 0; i < regionRows.Length; i++)
                        {
                            HOperatorSet.GetGrayval(imgR, regionRows[i], regionCols[i], out valR);
                            HOperatorSet.GetGrayval(imgG, regionRows[i], regionCols[i], out valG);
                            HOperatorSet.GetGrayval(imgB, regionRows[i], regionCols[i], out valB);
                            SourceImage.SetRGBPixel(regionCols[i], regionRows[i], Color.FromArgb(valR.I, valG.I, valB.I));
                        }

                        HBCoreImage = new TImage(SourceImage.Width, SourceImage.Height, SourceImage.Pixelformat);

                        if (flowLayoutPanel_Templates.Controls.Count > 1)
                        {
                            backprojection.multi_hist_backprojection_classification(SourceImage, TemplateList, HBCoreImage, Convert.ToInt32(textBox_Bins.Text));
                        }
                        else if (flowLayoutPanel_Templates.Controls.Count == 1)
                        {
                            backprojection.hist_backprojection(SourceImage, TemplateList[0], HBCoreImage, Convert.ToInt32(textBox_Bins.Text));
                        }
                        try
                        {
                            cadControlWin_cellCores.ImageBMP = null;
                        }
                        catch { }
                        cadControlWin_cellCores.ImageBMP = (Bitmap)HBCoreImage.Image.Clone();
                        statusBar_Steps.Value = statusBar_Steps.Breakpoints[1].ProgressPosition;
                    }
                    catch
                    {
                        MessageBox.Show("Fehler in Schritt 3");
                        inProcess = false;

                        this.Invoke((MethodInvoker)delegate()
                        {
                            this.Cursor = Cursors.Default;
                        });
                        return;
                    }
                    //-------------------------------------------------------------------------------------------------------
                    //-------------------------------------------------------------------------------------------------------
                    //SCHRITT 4: ZELLKERNREGIONEN ANPASSEN   -> HAL-REGIONEN ERZEUGEN
                    //                                       -> OPENING ZUR TRENNUNG ZUSAMMENGEWACHSENER ZELLKERNE
                    //                                       -> ZELLKERNBEREICH DER DEN ZELLBEREICH ÜBERLAPPT -> ABSCHNEIDEN
                    //                                       -> PRÜFEN OB ZELLKERN-SP INNERHALB DER ZELLKERNREGION LIEGT
                    //                                          WENN NICHT DANN SP DES GRÖSSTEN INNENKREISES ALS ZK-SP SETZEN
                    //                                       -> GEMEINSAME SCHNITTMENGE VERSCHIEDENER KERNE VON KERNREGIONEN
                    //                                          SUBTRAHIEREN 
                    //-------------------------------------------------------------------------------------------------------
                    //-------------------------------------------------------------------------------------------------------
                    HObject RegionTemplateR, RegionTemplateG;

                    try
                    {
                        cells = CellCoreWorker.EditCellCores(window, cellImg_HAL, HBCoreImage, cells, Convert.ToInt32(pars[9]), out RegionTemplateR, out RegionTemplateG);

                        ClusterClassification.checkSingleCellsCores(cells, out cells);

                        CellCoreWorker.DecisionTreeCoreSegmentation.checkCellCores(cells, RegionTemplateR, RegionTemplateG, out cells);
                        CellCoreWorker.DecisionTreeCoreSegmentation.deleting_to_small_Cores(cells, out cells);

                        //Zuweisung der Zellkerne zu den Zellen 
                        for (int i = 0; i < cells.Count; i++)
                        {
                            for (int j = 0; j < cells[i].CoreInfo.Count; j++)
                            {
                                SimpleCADControl.Vector2D[] contourArr = HalObjToCADControl.createCADContourPoints(cells[i].CoreInfo[j].cellCore, Convert.ToInt32(pars[8]));
                                cellCoreData core = cells[i].CoreInfo[j];
                                core.cellCoreContour = genCorePolyFromCoreContourList(contourArr);
                                cells[i].CoreInfo[j] = core;
                            }
                        }
                    }
                    catch
                    {
                        MessageBox.Show("Fehler in Schritt 4");
                        inProcess = false;

                        this.Invoke((MethodInvoker)delegate()
                        {
                            this.Cursor = Cursors.Default;
                        });
                        return;
                    }
                }
                //-------------------------------------------------------------------------------------------------------
                //-------------------------------------------------------------------------------------------------------
                //SCHRITT 5: TRENNUNG ZUSAMMENHÄNGENDER ZELLEN
                //-------------------------------------------------------------------------------------------------------
                //-------------------------------------------------------------------------------------------------------
                if ((checkBox_cellsegmentation.Checked == true) && (checkBox_cellcoredetection.Checked == true) && ((checkBox_cellclustersplittingA.Checked == true) || (checkBox_cellclustersplittingB.Checked == true)))
                {
                    mainWindow.GeoObjects.Clear();
                    cellPolyCollection.Clear();
                    //Bitmap erstellen für den Fall, dass eine Zellseparation über die Wachstumssimulation der Kernregionen laufen soll
                    Bitmap img = new Bitmap(mainWindow.Image);

                    //Original Zelldaten-Liste speichern, damit die Zellkerne erhalten bleiben. Die werden nämlich bei der
                    //Zelltrennung eliminiert.
                    cells_SAV = new List<cellData>(cells);

                    List<int> clusterIndexListe = new List<int>();
                    List<cellSeparation> cellSeparationList = new List<cellSeparation>();

                    try
                    {
                        bool alreadyInserted = false;
                        //Index der Cluster in der Liste dann in einer separaten Liste speichern
                        for (int i = 0; i < cells.Count; i++)
                        {
                            //Wenn eine Einzelzelle mehr als einen Kern enthält -> Status Cluster = true setzen
                            if (cells[i].isCluster == false)
                            {
                                if (cells[i].CoreInfo.Count > 1)
                                {
                                    clusterIndexListe.Add(i);
                                    alreadyInserted = true;
                                    cells[i].isCluster = true;
                                }
                            }
                            if (cells[i].isCluster == true)
                            {
                                //Wenn ein Cluster keinen oder einen Zellkern enthält den Status
                                //auf Einzelzelle setzen
                                if (cells[i].CoreInfo.Count < 2)
                                    cells[i].isCluster = false;
                                else
                                {
                                    if (alreadyInserted == false)
                                        clusterIndexListe.Add(i);
                                }
                            }
                            alreadyInserted = false;
                        }
                        //-----------------------------------------------------------------------
                        //Visualisierung im Halcon-Bild
                        //-----------------------------------------------------------------------
                        for (int i = 0; i < cells.Count; i++)
                        {
                            if (cells[i].isCluster == true)
                            {
                                HOperatorSet.SetColor(window, "pink");
                                HOperatorSet.DispObj(cells[i].cellRegion, window);
                            }
                        }

                        int counter = 0;

                        HObject img_Saturation_HAL;
                        TImage img_Saturation = imageWorker.calcRGBImgSaturation(new TImage(mainWindow.Image));

                        HalconDotNet.HOperatorSet.GenImageInterleaved(out img_Saturation_HAL, img_Saturation.firstPixel, "bgr",
                                                                      img_Saturation.Width, img_Saturation.Height, 0, "byte",
                                                                      0, 0, 0, 0, -1, 0);



                        //HOperatorSet.SetSystem("neighborhood", 4);
                        HTuple areaTemp, row, col;
                        //for (int i = 0; i < clusterIndexListe.Count; i++)
                        System.Threading.Tasks.Parallel.For(0, clusterIndexListe.Count, i =>
                        {
                            cellSeparation cellSeparator = null;

                            //Soll kontextbasierte Dilatation ausgeführt werden
                            if (Convert.ToBoolean(pars[16]) == true)
                            {
                                //Prüfen ob die Minimalfläche für Cluster für die kontextbasierte Dilatation unterschritten wurde
                                //Wenn ja -> standard Trennalgo asuführen!
                                HOperatorSet.AreaCenter(cells_SAV[clusterIndexListe[i]].cellRegion, out areaTemp, out row, out col);
                                if (areaTemp.I < Convert.ToInt32(pars[17]))
                                    cellSeparator = new cellSeparation(cells_SAV[clusterIndexListe[i]], (int)pars[1], false, window);
                                else
                                    cellSeparator = new cellSeparation(cells_SAV[clusterIndexListe[i]], (int)pars[1], true, window);
                            }
                            else
                                cellSeparator = new cellSeparation(cells_SAV[clusterIndexListe[i]], (int)pars[1], false, window);

                            List<cellCoreData> cellcores = new List<cellCoreData>();
                            for (int j = 0; j < cells_SAV[clusterIndexListe[i]].CoreInfo.Count; j++)
                            {
                                cellCoreData core = new cellCoreData();
                                core.cellCore = cells_SAV[clusterIndexListe[i]].CoreInfo[j].cellCore;
                                core.SP = cells_SAV[clusterIndexListe[i]].CoreInfo[j].SP;
                                cellcores.Add(core);
                            }

                            if (checkBox_HalconDebugMode.Checked == true)
                            {
                                if (cellSeparator.doContextDilation == false)
                                    cellSeparator.separateCellsInCluster(cellcores, (int)pars[1], window);
                                else
                                    cellSeparator.seperateCellsWithContextDilation(img.Width, img.Height, window);
                            }
                            else
                            {
                                if (cellSeparator.doContextDilation == false)
                                    cellSeparator.separateCellsInCluster(cellcores, (int)pars[1]);
                                else
                                    cellSeparator.seperateCellsWithContextDilation(img.Width, img.Height);
                            }
                            Application.DoEvents();
                            counter++;
                            //Statusbar aktualisieren
                            statusBar_Steps.Value = statusBar_Steps.Breakpoints[1].ProgressPosition + ((double)counter / clusterIndexListe.Count) * (statusBar_Steps.Breakpoints.Last().ProgressPosition - statusBar_Steps.Breakpoints[1].ProgressPosition);

                            HTuple area_diff, row_diff, col_diff;
                            HObject sumIndCells, regionDiff, connectedRegionDiff, selectedRegionDiff, selectedReg;
                            HOperatorSet.GenEmptyObj(out sumIndCells);
                            HOperatorSet.GenEmptyObj(out regionDiff);
                            for (int j = 0; j < cellSeparator.getseparatedCells().Count; j++)
                            {
                                //Einzelzellregionen zu einer Region vereinigen
                                HOperatorSet.Union2(sumIndCells, cellSeparator.getseparatedCells()[j].cellRegion, out sumIndCells);
                            }
                            //Nun die im Cluster befindlichen Einzelzellregionen von der Cluster-Zellregion subtrahieren, falls nicht trennbare
                            //Kerne vorhanden sind
                            if (cellSeparator.isolationFailed == true)
                            {
                                //Vorhandene Einzelzell-Regionen von der Clusterregion subtrahieren
                                //und die übrig gebliebene(n) Region(en) auch anzeigen
                                HOperatorSet.Difference(cells_SAV[clusterIndexListe[i]].cellRegion, sumIndCells, out regionDiff);
                                HOperatorSet.Connection(regionDiff, out connectedRegionDiff);
                                //Hier der Parameter beeinflusst die zu übernehmenden Regionen in den Clustern, wo teilweise keine Trennlinien
                                //erzeugt werden konnten
                                HOperatorSet.SelectShape(connectedRegionDiff, out selectedRegionDiff, "area", "and", 500, 10000000);
                                for (int k = 0; k < selectedRegionDiff.CountObj(); k++)
                                {
                                    HOperatorSet.SelectObj(selectedRegionDiff, out selectedReg, k + 1);
                                    HOperatorSet.AreaCenter(selectedReg, out area_diff, out row_diff, out col_diff);
                                    //Nicht trennbare Regionen als eine Zelle in neue Zelliste schreiben
                                    if (area_diff >= 10)
                                    {
                                        cellSeparator.nonSeparatedRegions = selectedReg;
                                        cellData newcell = new cellData();
                                        newcell.cellRegion = selectedReg;
                                        //Anzahl Kerne die in einer Region mit nicht trennbaren Kernen sind noch rausfinden, problem ist 
                                        //aber gerad das die Zellkerne coreInfo in der validCoresInCells_2 Liste durch die Zellseparation entfernt wurden
                                        List<cellCoreData> coresInsideRegion = cellSeparator.getCoresInSubRegion(selectedReg, cells_SAV[clusterIndexListe[i]].CoreInfo);
                                        newcell.CoreInfo = coresInsideRegion;
                                        newcell.isCluster = false;
                                        newcell.nr = newCellList.Count + 1;
                                        newCellList.Add(newcell);
                                    }
                                }
                            }
                            cellSeparationList.Add(cellSeparator);
                            //Es muss eine neue Zell-Liste aufgebaut werden weil durch den Zelltrennalgo die CoreInfo Liste
                            //in der cell-Liste manipuliert wird und nach der Zelltrennung der ursprüngliche Cluster
                            //gelöscht werden soll, weil dafür ja die darin enthaltenen Einzelzellen berechnet wurden
                            for (int j = 0; j < cellSeparator.getseparatedCells().Count; j++)
                            {
                                cellData newcell = new cellData();
                                newcell.cellRegion = cellSeparator.getseparatedCells()[j].cellRegion;
                                newcell.CoreInfo = cellSeparator.getseparatedCells()[j].CoreInfo;
                                newcell.isCluster = cellSeparator.getseparatedCells()[j].isCluster;
                                newcell.nr = newCellList.Count + 1;
                                newCellList.Add(newcell);
                            }
                        });
                        //}
                        Application.DoEvents();

                        //Alle bereits vorher ermittelten Einzelzellen der neuen Zellliste hinzufügen
                        for (int j = 0; j < cells.Count; j++)
                        {
                            if (cells[j].isCluster == false)
                            {
                                //Einzelzellen auch in die neue Zelliste schreiben
                                cells[j].nr = newCellList.Count + 1;
                                newCellList.Add(cells[j]);
                            }
                        }
                        statusBar_Steps.Value = statusBar_Steps.Breakpoints[statusBar_Steps.Breakpoints.Count - 1].ProgressPosition;

                        cells.Clear();
                        cells = newCellList;
                    }
                    catch (System.Exception ex)
                    {
                        MessageBox.Show("Fehler in Schritt 5 " + ex.Message);
                        inProcess = false;

                        this.Invoke((MethodInvoker)delegate()
                        {
                            this.Cursor = Cursors.Default;
                        });
                        return;
                    }
                }
                //-------------------------------------------------------------------------------------------------------
                //Zellstatistiken ermitteln
                //-------------------------------------------------------------------------------------------------------
                cells = calcCellStatistics(cells, checkBox_CalcSaturation.Checked);
                //-------------------------------------------------------------------------------------------------------
                //Zwischenschritt: Wenn gewünscht -> unpassende Randzellen löschen
                //-------------------------------------------------------------------------------------------------------
                if (checkBox_IgnoreBorderCells.Checked == true)
                {
                    Bitmap bmp = new Bitmap(mainWindow.Image);
                    cells = HalconFunctions.eliminateBorderCells(cells, Convert.ToInt32(pars[13]), Convert.ToInt32(pars[14]), bmp.Width, bmp.Height, window);
                }
                //-------------------------------------------------------------------------------------------------------
                //Regionen aus Zellliste entfernen die aufgrund der Sättigungs-Varianz als Hintergrundartefakte oder
                //blasse Zellreste eingeordnet und somit aus der Zellliste enfternt werden können 
                //-------------------------------------------------------------------------------------------------------
                if (Convert.ToBoolean(pars[11]) == true)
                {
                    cells = eleminateBackgroundNoise(cells, Convert.ToDouble(pars[12]));
                    cells = eleminateBackgroundNoise(cells, Convert.ToDouble(pars[12]));
                    cells = eleminateBackgroundNoise(cells, Convert.ToDouble(pars[12]));
                }
                //-------------------------------------------------------------------------------------------------------
                //Zellvitalität bestimmen (tot/lebend)
                //-------------------------------------------------------------------------------------------------------            
                cells = cellAnalyser.analyseCellVitality(cells, Convert.ToString(pars[23]), Convert.ToString(pars[24]), Convert.ToString(pars[25]),
                                                         Convert.ToDouble(pars[26]), Convert.ToDouble(pars[27]), 
                                                         Convert.ToDouble(pars[28]), Convert.ToDouble(pars[29]),
                                                         Convert.ToDouble(pars[30]), Convert.ToDouble(pars[31]));
                //--------------------------------------------------------------------------------------------------------
                //--------------------------------------------------------------------------------------------------------
                //SCHRITT 6: VISUALISIERUNG DER DATEN
                //--------------------------------------------------------------------------------------------------------
                //--------------------------------------------------------------------------------------------------------
                Random rnd = new Random();
                Color[] colorTable = new Color[16];
                colorTable[0] = Color.Green;
                colorTable[1] = Color.Red;
                colorTable[2] = Color.Cyan;
                colorTable[3] = Color.Yellow;
                colorTable[4] = Color.Blue;
                colorTable[5] = Color.Orange;
                colorTable[6] = Color.White;
                colorTable[7] = Color.Magenta;
                colorTable[8] = Color.Black;
                colorTable[9] = Color.Pink;
                colorTable[10] = Color.Gold;
                colorTable[11] = Color.Firebrick;
                colorTable[12] = Color.Sienna;
                colorTable[13] = Color.Salmon;
                colorTable[14] = Color.Tan;
                colorTable[15] = Color.Plum;

                for (int j = 0; j < cells.Count; j++)
                {
                    //Es wird eine Zelle übergeben und eine Liste mit den
                    //Vector2D-Daten zurückgegeben. Also die Zellkontur und ggf. eine Liste mit den Löcherkonturen
                    cellAndHolesContPoints cellContourListWithHoles = HalObjToCADControl.createCADContourPointsList(cells[j], Convert.ToInt32(pars[7]), Convert.ToInt32(pars[8]));

                    if (cellContourListWithHoles.cellHolesContourPoints != null)
                    {
                        Polygon[] cellHoles = new Polygon[cellContourListWithHoles.cellHolesContourPoints.Count];

                        for (int k = 0; k < cellContourListWithHoles.cellHolesContourPoints.Count; k++)
                        {
                            if (cellContourListWithHoles.cellHolesContourPoints[k].Length >= 3)
                            {
                                Polygon cellHole = new Polygon(cellContourListWithHoles.cellHolesContourPoints[k]);
                                cellHole.Parent = mainWindow;
                                cellHole.IsActive = false;
                                cellHole.DrawingColor = Color.Green;
                                cellHole.DrawingWidth = 2;
                                cellHole.Layer = 3;
                                cellHoles[k] = cellHole;
                            }
                        }

                        MultiPolygon cellWithHoles = new MultiPolygon(cellHoles, cellContourListWithHoles.cellContourPoints);
                        cellWithHoles.Parent = mainWindow;
                        cellWithHoles.IsActive = false;
                        cellWithHoles.DrawingColor = colorTable[rnd.Next(0, colorTable.Length - 1)];
                        cellWithHoles.DrawingWidth = 2;
                        //Wenn eine Zelle lebt                                  -> Layer 1 zuweisen
                        //Wenn eine Zelle lebt weil sie sich gerade geteilt hat -> Layer 5 zuweisen
                        //Wenn eine Zelle tot ist                               -> Layer 4 zuweisen
                        if (cells[j].wasBarbelCell == true)
                            cellWithHoles.Layer = 5;
                        else
                        {
                            if (cells[j].isAlive == true)
                                cellWithHoles.Layer = 1;
                            else
                                cellWithHoles.Layer = 4;
                        }

                        mainWindow.GeoObjects.Add(cellWithHoles);
                        mainWindow.GeoObjects.AddRange(cellHoles);

                        //Nur Polygone die Zellen darstellen sollen im Dictionary den Zelldaten in cells zugeordnet werden. 
                        //Zelllöcher die auch Polygone im CAD-Control vorhanden sind sollen natürlich nicht in die Zellstatistik als
                        //eigenständige Zellen einfließen, deswegen hier die Abfrage nach dem Layer
                        DataGridViewRow newRow = new DataGridViewRow();

                        if (((mainWindow.GeoObjects[mainWindow.GeoObjects.Count - 1 - cellHoles.Length] as Polygon).Layer == 1) ||
                            ((mainWindow.GeoObjects[mainWindow.GeoObjects.Count - 1 - cellHoles.Length] as Polygon).Layer == 4) ||
                            ((mainWindow.GeoObjects[mainWindow.GeoObjects.Count - 1 - cellHoles.Length] as Polygon).Layer == 5))
                        {
                            cellPolyCollection.Add(mainWindow.GeoObjects[mainWindow.GeoObjects.Count - 1] as Polygon, cells[j]);
                            if (Convert.ToBoolean(pars[10]) == true)
                            {
                                (mainWindow.GeoObjects[mainWindow.GeoObjects.Count - 1 - cellHoles.Length] as Polygon).Label = Convert.ToString(cells[j].nr);
                                (mainWindow.GeoObjects[mainWindow.GeoObjects.Count - 1 - cellHoles.Length] as Polygon).ShowLabel = true;
                            }
                        }
                        //Wenn die Zelle sich gerade geteilt hat (hantelförmige Zelle) ist sie unabh. von ihrer Größe am leben
                        if (cells[j].wasBarbelCell == true)
                            newRow.CreateCells(dataGridView_CellStatistics, cells[j].nr, cells[j].statistics.cellArea, cells[j].statistics.coreCount, Math.Round(cells[j].statistics.circularity, 2), Math.Round(cells[j].statistics.saturationDeviation, 2), Math.Round(cells[j].statistics.cellForm, 2), "alive");
                        else
                        {
                            //Handelt es sich um keine sich gerade geteilte Zelle Vitalitätsproperty der durchgeführten Analyse der Zelle abfragen und entsprechend den Status im DataGrid setzen 
                            if (cells[j].isAlive == true)
                                newRow.CreateCells(dataGridView_CellStatistics, cells[j].nr, cells[j].statistics.cellArea, cells[j].statistics.coreCount, Math.Round(cells[j].statistics.circularity, 2), Math.Round(cells[j].statistics.saturationDeviation, 2), Math.Round(cells[j].statistics.cellForm, 2), "alive");
                            else
                                newRow.CreateCells(dataGridView_CellStatistics, cells[j].nr, cells[j].statistics.cellArea, cells[j].statistics.coreCount, Math.Round(cells[j].statistics.circularity, 2), Math.Round(cells[j].statistics.saturationDeviation, 2), Math.Round(cells[j].statistics.cellForm, 2), "dead");
                        }
                        newRow.ReadOnly = false;
                        cellDataPolyCollection.Add(newRow, mainWindow.GeoObjects[mainWindow.GeoObjects.Count - 1 - cellHoles.Length] as Polygon);
                        dataGridView_CellStatistics.Invoke(Delegate.CreateDelegate(typeof(ViewInDataGridDelegate), this, "ViewInDataGrid"), newRow);
                        update();
                        Application.DoEvents();
                    }
                    else
                    {
                        if (cellContourListWithHoles.cellContourPoints.Length > 2)
                        {
                            mainWindow.GeoObjects.Add(genCellPolyFromCellContourList(cellContourListWithHoles.cellContourPoints, colorTable[rnd.Next(0, colorTable.Length - 1)]));

                            //Wenn eine Zelle lebt                                  -> Layer 1 zuweisen
                            //Wenn eine Zelle lebt weil sie sich gerade geteilt hat -> Layer 5 zuweisen
                            //Wenn eine Zelle tot ist                               -> Layer 4 zuweisen
                            if (cells[j].wasBarbelCell == true)
                                mainWindow.GeoObjects[mainWindow.GeoObjects.Count - 1].Layer = 5;
                            else
                            {
                                if (cells[j].isAlive == true)
                                    mainWindow.GeoObjects[mainWindow.GeoObjects.Count - 1].Layer = 1;
                                else
                                    mainWindow.GeoObjects[mainWindow.GeoObjects.Count - 1].Layer = 4;
                            }

                            DataGridViewRow newRow = new DataGridViewRow();

                            //Nur Polygone die Zellen darstellen sollen im Dictionary den Zelldaten in cells zugeordnet werden. 
                            //Zelllöcher die auch Polygone im CAD-Control vorhanden sind sollen natürlich nicht in die Zellstatistik als
                            //eigenständige Zellen einfließen, deswegen hier die Abfrage nach dem Layer
                            if (((mainWindow.GeoObjects[mainWindow.GeoObjects.Count - 1] as Polygon).Layer == 1) ||
                                ((mainWindow.GeoObjects[mainWindow.GeoObjects.Count - 1] as Polygon).Layer == 4) ||
                                ((mainWindow.GeoObjects[mainWindow.GeoObjects.Count - 1] as Polygon).Layer == 5))
                            {
                                cellPolyCollection.Add(mainWindow.GeoObjects[mainWindow.GeoObjects.Count - 1] as Polygon, cells[j]);
                                if (Convert.ToBoolean(pars[10]) == true)
                                {
                                    (mainWindow.GeoObjects[mainWindow.GeoObjects.Count - 1] as Polygon).Label = Convert.ToString(cells[j].nr);
                                    (mainWindow.GeoObjects[mainWindow.GeoObjects.Count - 1] as Polygon).ShowLabel = true;
                                }
                            }
                            //Wenn die Zelle sich gerade geteilt hat (hantelförmige Zelle) ist sie unabh. von ihrer Größe am leben
                            if (cells[j].wasBarbelCell == true)
                                newRow.CreateCells(dataGridView_CellStatistics, cells[j].nr, cells[j].statistics.cellArea, cells[j].statistics.coreCount, Math.Round(cells[j].statistics.circularity, 2), Math.Round(cells[j].statistics.saturationDeviation, 2), Math.Round(cells[j].statistics.cellForm, 2), "alive");
                            else
                            {
                                //Handelt es sich um keine sich gerade geteilte Zelle Vitalitätsproperty der durchgeführten Analyse der Zelle abfragen und entsprechend den Status im DataGrid setzen 
                                if (cells[j].isAlive == true)
                                    newRow.CreateCells(dataGridView_CellStatistics, cells[j].nr, cells[j].statistics.cellArea, cells[j].statistics.coreCount, Math.Round(cells[j].statistics.circularity, 2), Math.Round(cells[j].statistics.saturationDeviation, 2), Math.Round(cells[j].statistics.cellForm, 2), "alive");
                                else
                                    newRow.CreateCells(dataGridView_CellStatistics, cells[j].nr, cells[j].statistics.cellArea, cells[j].statistics.coreCount, Math.Round(cells[j].statistics.circularity, 2), Math.Round(cells[j].statistics.saturationDeviation, 2), Math.Round(cells[j].statistics.cellForm, 2), "dead");
                            }
                            newRow.ReadOnly = false;
                            cellDataPolyCollection.Add(newRow, mainWindow.GeoObjects[mainWindow.GeoObjects.Count - 1] as Polygon);
                            dataGridView_CellStatistics.Invoke(Delegate.CreateDelegate(typeof(ViewInDataGridDelegate), this, "ViewInDataGrid"), newRow);
                            update();
                            Application.DoEvents();
                        }
                    }
                }
                //-------------------------------------------------------------------------------------------------------
                //Zellkerne nach Wunsch visualisieren lassen
                //-------------------------------------------------------------------------------------------------------
                if (checkBox_ShowCores.Checked == true)
                {
                    for (int j = 0; j < cells.Count; j++)
                    {
                        for (int k = 0; k < cells[j].CoreInfo.Count; k++)
                        {
                            mainWindow.GeoObjects.Add(genCorePolyFromCoreContourList(HalObjToCADControl.createCADContourPoints(cells[j].CoreInfo[k].cellCore, 10)));
                        }
                    }
                    update();
                }   
                //-------------------------------------------------------------------------------------------------------
                //Wenn Randzellen eliminiert wurden müssen die DataGrid-Einträge der Randzellen gelöscht werden und die 
                //Zellennummern neu vergeben werden -> Syncronisieren
                //-------------------------------------------------------------------------------------------------------
                this.Invoke((MethodInvoker)delegate()
                {
                    toolStripButton_SyncHalObjWithGeoObj_Click(this, new EventArgs());
                });            
                update();

                inProcess = false;

                this.Invoke((MethodInvoker)delegate()
                {
                    this.Cursor = Cursors.Default;
                });
                timer.Stop();
                TimeToTextbox(timer);
            }
        }

        private void syncVisualizationWithCellDataList(List<cellData> cells, Dictionary<DataGridViewRow, Polygon> cellDataPolyCollection, Dictionary<Polygon, cellData> cellPolyCollection)
        {
            for (int i = 0; i < cellPolyCollection.Values.Count; i++)
            {
                bool cellInList = false;
                //Prüfen ob Zelle in Dictionary enthalten ist
                foreach (var item in cells)
                {
                    if (item.cellRegion == cellPolyCollection.Values.ElementAt(i).cellRegion)
                    {
                        cellInList = true;
                        break;
                    }
                }
                //Wenn die Zelle nicht in der Liste enthalten ist muss das Polygon aus dem Fenster und der entsprechende Datensatz
                //aus dem Datagrid gelöscht werden
                if (cellInList == false)
                {
                    mainWindow.GeoObjects.Remove(cellPolyCollection.Keys.ElementAt(i));
                    this.Invoke((MethodInvoker)delegate()
                    {
                        dataGridView_CellStatistics.Rows.Remove(cellDataPolyCollection.Keys.ElementAt(i));
                    });
                    cellDataPolyCollection.Remove(cellDataPolyCollection.Keys.ElementAt(i));
                    cellPolyCollection.Remove(cellPolyCollection.Keys.ElementAt(i));
                    i--;
                }
            }
        }

        private void ViewInDataGrid(DataGridViewRow row)
        {
            dataGridView_CellStatistics.Rows.Add(row);
        }

        private void TimeToTextbox(Stopwatch timer)
        {
            if (InvokeRequired)
            {
                Invoke(new TimeToTextboxDelegate(TimeToTextbox), timer);
                return;
            }
            textBox_Time.Text = Convert.ToString(Math.Round((double)timer.ElapsedMilliseconds / 1000, 2));
        }
        private void TimeToTextboxStapel(Stopwatch timer)
        {
            if (InvokeRequired)
            {
                Invoke(new TimeToTextboxStapelDelegate(TimeToTextboxStapel), timer);
                return;
            }
            textBox_EllapsedTimeStapel.Text = Convert.ToString(Math.Round((double)timer.ElapsedMilliseconds / 1000, 2));
        }
        private void fillCellStatGrid(List<cellData> cells)
        {
            if (InvokeRequired)
            {
                Invoke(new ShowCellStatisticsInGridDelegate(fillCellStatGrid), cells);
                return;
            }

            dataGridView_CellStatistics.Rows.Clear();

            for (int i = 0; i < cells.Count; i++)
            {
                dataGridView_CellStatistics.Rows.Add(cells[i].nr, cells[i].statistics.cellArea, cells[i].statistics.coreCount, Math.Round(cells[i].statistics.cellForm, 2));
            }
        }
        private void showElapsedTime()
        {
            this.Invoke((MethodInvoker)delegate()
            {
                textBox_Time.Text = Convert.ToString(Math.Round(Convert.ToDouble((double)timer.ElapsedMilliseconds / 1000), 2));
            });
        }

        private void toolStripButton_Stop_Click(object sender, EventArgs e)
        {
            if (inProcess)
            {
                breakLoop = true;

            }
            setDefaultVarAlgo();
            thread.Abort();
            if (threadPool != null)
            {
                foreach (var t in threadPool)
                {
                    try
                    {
                        t.Abort();
                    }
                    catch { }
                }
            }
        }

        private void button_CreateTemplate_Click(object sender, EventArgs e)
        {
            //Tool zur Erstellung von Farbtemplates für die Zellkernerkennung
            AnnaLiese.Main templateCtr = new AnnaLiese.Main();
            templateCtr.Show();
        }
        /// <summary>
        /// Event tritt auf, wenn in dem DataGrid für die Zellstatistiken ein anderer Datensatz ausgewählt wurde.
        /// In dem Fall werden alle bisher selektierten Zellen im Fenster deselektiert und die neu ausgewählte Zelle
        /// auf den Status aktiv gesetzt.Dadurch wird die Zelle im Bildfenster automatisch selektiert
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView_CellStatistics_SelectionChanged(object sender, EventArgs e)
        {
            if (dataGridView_CellStatistics.SelectedRows.Count > 0)
            {
                try
                {
                    mainWindow.DeselectAllObjects();

                    cellDataPolyCollection[dataGridView_CellStatistics.SelectedRows[0]].IsActive = true;

                    //Wenn die selektierte Zeile ausserhalb des aktuellen Sichtbereiches im Datagrid liegt -> den Sichtbereich auf neu selektierte
                    //Zeile einstellen
                    double anzRows = (double)(dataGridView_CellStatistics.Height - dataGridView_CellStatistics.ColumnHeadersHeight) / dataGridView_CellStatistics.Rows[0].Height;
                    if ((dataGridView_CellStatistics.SelectedRows[0].Index < dataGridView_CellStatistics.FirstDisplayedScrollingRowIndex) || (dataGridView_CellStatistics.SelectedRows[0].Index >= (dataGridView_CellStatistics.FirstDisplayedScrollingRowIndex + (int)anzRows)))
                    {
                        dataGridView_CellStatistics.FirstDisplayedScrollingRowIndex = dataGridView_CellStatistics.SelectedRows[0].Index;
                    }

                    double x, y, x2, y2;
                    x = cellDataPolyCollection[dataGridView_CellStatistics.SelectedRows[0]].EditPoints.Select(s => s.X).Min();
                    x2 = cellDataPolyCollection[dataGridView_CellStatistics.SelectedRows[0]].EditPoints.Select(s => s.X).Max();
                    y = cellDataPolyCollection[dataGridView_CellStatistics.SelectedRows[0]].EditPoints.Select(s => s.Y).Min();
                    y2 = cellDataPolyCollection[dataGridView_CellStatistics.SelectedRows[0]].EditPoints.Select(s => s.Y).Max();

                    mainWindow.FocusArea(new SimpleCADControl.Vector2D(x, y), new SimpleCADControl.Vector2D(x2, y2));
                    foreach (var flashingPanel in cellDataPolyCollection.Select(s => s.Value).Where(w => w.Flash == true))
                    {
                        flashingPanel.Flash = false;
                    }
                    cellDataPolyCollection[dataGridView_CellStatistics.SelectedRows[0]].Flash = true;
                    update();
                }
                catch { }
            }
        }

        private void dataGridView_CellStatistics_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.Delete)
            {
                if (dataGridView_CellStatistics.SelectedRows.Count > 0)
                {
                    //Im Dictonary das Polygon und die zugehörigen Zelldaten löschen
                    cellPolyCollection.Remove(cellDataPolyCollection[dataGridView_CellStatistics.SelectedRows[0]]);
                    mainWindow.GeoObjects.Remove(cellDataPolyCollection[dataGridView_CellStatistics.SelectedRows[0]]);
                    //Im Dictonary das Polygon und den zugehörigen Datensatz fürs Datagrid der Zellstatistik löschen
                    cellDataPolyCollection.Remove(dataGridView_CellStatistics.SelectedRows[0]);
                    update();
                }
            }
        }

        private void doubleSlider_ThreshR_ValueChanged(object sender, EventArgs e)
        {
            if (checkBox_dynActualisation.Checked)
                B_Run_Click(sender, e);
        }
        private void doubleSlider_ThreshG_ValueChanged(object sender, EventArgs e)
        {
            if (checkBox_dynActualisation.Checked)
                B_Run_Click(sender, e);
        }
        private void doubleSlider_ThreshB_ValueChanged(object sender, EventArgs e)
        {
            if (checkBox_dynActualisation.Checked)
                B_Run_Click(sender, e);
        }
        private void singleSlider_Area_ValueChanged(object sender, EventArgs e)
        {
            if (checkBox_dynActualisation.Checked)
                B_Run_Click(sender, e);
        }
        private void doubleSlider_HolesThreshR_ValueChanged(object sender, EventArgs e)
        {
            if (checkBox_dynActualisation.Checked)
                B_Run_Click(sender, e);
        }
        private void doubleSlider_HolesThreshG_ValueChanged(object sender, EventArgs e)
        {
            if (checkBox_dynActualisation.Checked)
                B_Run_Click(sender, e);
        }
        private void doubleSlider_HolesThreshB_ValueChanged(object sender, EventArgs e)
        {
            if (checkBox_dynActualisation.Checked)
                B_Run_Click(sender, e);
        }

        private void deleteAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            bool cellTemplateClicked = false;

            //Prüfen ob das Delete All in der Zelltemplate-Liste geklickt wurde oder in der Zellkerntemplate-Liste
            for (int i = 0; i < flowLayoutPanel_CellSegTemplates.Controls.Count; i++)
            {
                if (((CustomControls.HB_Template_Control)(flowLayoutPanel_CellSegTemplates.Controls[i])).clicked == true)
                {
                    cellTemplateClicked = true;
                }
            }
            if (cellTemplateClicked == true)
            {
                int counts = flowLayoutPanel_CellSegTemplates.Controls.Count;

                for (int i = 0; i < counts; i++)
                {
                    flowLayoutPanel_CellSegTemplates.Controls.RemoveAt(0);
                    TemplateCellSegList.RemoveAt(0);
                }
                flowLayoutPanel_CellSegTemplates.Show();
            }
            else
            {
                int counts = flowLayoutPanel_Templates.Controls.Count;

                for (int i = 0; i < counts; i++)
                {
                    flowLayoutPanel_Templates.Controls.RemoveAt(0);
                    TemplateList.RemoveAt(0);
                }
                flowLayoutPanel_Templates.Show();
            }
        }

        private void checkBox_FindCellHoles_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox_FindCellHoles.Checked == true)
            {
                if (checkBox_EditRGBHolesSimultan.Checked == true)
                {
                    doubleSlider_HolesThreshRGB.Enabled = true;
                    doubleSlider_HolesThreshR.Enabled = false;
                    doubleSlider_HolesThreshG.Enabled = false;
                    doubleSlider_HolesThreshB.Enabled = false;
                }
                else
                {
                    doubleSlider_HolesThreshRGB.Enabled = false;
                    doubleSlider_HolesThreshR.Enabled = true;
                    doubleSlider_HolesThreshG.Enabled = true;
                    doubleSlider_HolesThreshB.Enabled = true;
                }
            }
            else
            {
                doubleSlider_HolesThreshRGB.Enabled = false;
                doubleSlider_HolesThreshR.Enabled = false;
                doubleSlider_HolesThreshG.Enabled = false;
                doubleSlider_HolesThreshB.Enabled = false;
            }
            update();
        }

        private void saveParametersToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //Parameter speichern
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                SaveParameters(saveFileDialog1.FileName);
            }
        }
        private void loadParametersToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                if (openFileDialog2.ShowDialog() == DialogResult.OK)
                {
                    LoadParameters(openFileDialog2.FileName);
                }
            }
            catch
            {
                inProcess = false;
                bool status = checkBox_EditRGBSimultan.Checked;
                checkBox_EditRGBSimultan.Checked = false;
                checkBox_EditRGBSimultan.Checked = true;
                checkBox_EditRGBSimultan.Checked = status;
            }
        }

        public void LoadParameters(String fileName)
        {
            //Wird hier true gesetzt damit der Algorithmus nicht automatisch startet falls die dyn.Aktualisierung
            //aktiviert ist -> beim ValueChanged Event der Slider würde der Algo dann ja neu starten
            inProcess = true;
            doubleSlider_ThreshRGB.Enabled = true;
            doubleSlider_ThreshR.Enabled = true;
            doubleSlider_ThreshG.Enabled = true;
            doubleSlider_ThreshB.Enabled = true;
            Parameters.Load(fileName);
            SyncParameterClassWithGUIParameters();
            comboBox_SegmantationMethod_SelectedValueChanged(this, new EventArgs());
            inProcess = false;
            bool status = checkBox_EditRGBSimultan.Checked;
            checkBox_EditRGBSimultan.Checked = false;
            checkBox_EditRGBSimultan.Checked = true;
            checkBox_EditRGBSimultan.Checked = status;
        }

        public void SaveParameters(String fileName)
        {
            SyncGUIParametersWithParameterClass();
            Parameters.Save(fileName);
        }

        private void dataGridView_CellStatistics_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (dataGridView_CellStatistics.SelectedRows.Count > 0)
            {
                try
                {
                    mainWindow.DeselectAllObjects();

                    cellDataPolyCollection[dataGridView_CellStatistics.SelectedRows[0]].IsActive = true;
                    foreach (var flashingPanel in cellDataPolyCollection.Select(s => s.Value).Where(w => w.Flash == true))
                    {
                        flashingPanel.Flash = false;
                    }
                    cellDataPolyCollection[dataGridView_CellStatistics.SelectedRows[0]].Flash = true;
                    update();
                }
                catch { }
            }
        }

        private void comboBox_DCP_Levels_TextChanged(object sender, EventArgs e)
        {
            if (comboBox_DCP_Levels.Text != "")
            {
                try
                {
                    //Segmentierung+DCP-Berechnung zusammen durchführen
                    B_Run_Click(sender, e);

                }
                catch { }
            }
        }

        private void toolStripButton_SaveGeoObjects_Click(object sender, EventArgs e)
        {
            try
            {
                if (GeoObjects_Saved != null)
                    GeoObjects_Saved.Clear();
                GeoObjects_Saved = new List<GeoObject>(mainWindow.GeoObjects);
                toolStripButton_LoadGeoObjects.Enabled = true;
            }
            catch { }
        }

        private void toolStripButton_LoadGeoObjects_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < GeoObjects_Saved.Count; i++)
            {
                mainWindow.GeoObjects.Add(GeoObjects_Saved[i]);
            }
            update();
        }

        private void comboBox_SegmantationMethod_SelectedValueChanged(object sender, EventArgs e)
        {
            if (comboBox_SegmantationMethod.Text == "Threshold - Foreground")
            {
                dropDownPanel_Threshold_Foreground.Expanded = true;
                dropDownPanel_Threshold_Background.Expanded = false;
                dropDownPanel_HB.Expanded = false;
            }
            else if (comboBox_SegmantationMethod.Text == "Threshold - Background")
            {
                dropDownPanel_Threshold_Foreground.Expanded = false;
                dropDownPanel_Threshold_Background.Expanded = true;
                dropDownPanel_HB.Expanded = false;
            }
            else if (comboBox_SegmantationMethod.Text == "Histogram Backprojection")
            {
                dropDownPanel_Threshold_Foreground.Expanded = false;
                dropDownPanel_Threshold_Background.Expanded = false;
                dropDownPanel_HB.Expanded = true;
            }
        }

        private void cellAnalysisForm_Load(object sender, EventArgs e)
        {
            dropDownPanel_Threshold_Foreground.AddManagedControl(dropDownPanel_Threshold_Background);
            dropDownPanel_Threshold_Foreground.AddManagedControl(dropDownPanel_HB);

            dropDownPanel_Threshold_Background.AddManagedControl(dropDownPanel_HB);

            dropDownPanel_DCP_Calculation.AddManagedControl(dropDownPanel_SaturationProperties);
            dropDownPanel_DCP_Calculation.AddManagedControl(dropDownPanel_CellVitalityParams);
            dropDownPanel_DCP_Calculation.AddManagedControl(dropDownPanel_CoreTemplateParams);

            dropDownPanel_SaturationProperties.AddManagedControl(dropDownPanel_CellVitalityParams);
            dropDownPanel_SaturationProperties.AddManagedControl(dropDownPanel_CoreTemplateParams);

            dropDownPanel_CellVitalityParams.AddManagedControl(dropDownPanel_CoreTemplateParams);

            dropDownPanel_Threshold_Foreground.Expanded = false;
            dropDownPanel_Threshold_Background.Expanded = false;
            dropDownPanel_HB.Expanded = false;
            dropDownPanel_DCP_Calculation.Expanded = true;
            dropDownPanel_SaturationProperties.Expanded = true;
            dropDownPanel_CellVitalityParams.Expanded = true;
            dropDownPanel_CoreTemplateParams.Expanded = true;



            if (comboBox_SegmantationMethod.Text == "Threshold - Foreground")
            {
                dropDownPanel_Threshold_Foreground.Expanded = true;
                dropDownPanel_Threshold_Background.Expanded = false;
                dropDownPanel_HB.Expanded = false;
            }
            else if (comboBox_SegmantationMethod.Text == "Threshold - Background")
            {
                dropDownPanel_Threshold_Foreground.Expanded = false;
                dropDownPanel_Threshold_Background.Expanded = true;
                dropDownPanel_HB.Expanded = false;
            }
            else if (comboBox_SegmantationMethod.Text == "Histogram Backprojection")
            {
                dropDownPanel_Threshold_Foreground.Expanded = false;
                dropDownPanel_Threshold_Background.Expanded = false;
                dropDownPanel_HB.Expanded = true;
            }
        }

        private void button_LoadTemplatesCells_Click(object sender, EventArgs e)
        {
            openFileDialog1.Filter = "Alle kompatiblen Dateien (.jpg,.bmp,.png,.tif,.gif)|*.jpg;*.bmp;*.png;*.tif;*.gif|Bitmap (.bmp)|*.bmp";

            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                foreach (String filename in openFileDialog1.FileNames)
                {
                    AddCellTemplateControl(new TImage(filename));
                }
            }
        }

        private void toolStripButtonExportToExcel_Click(object sender, EventArgs e)
        {
            if (saveFileDialogExcel.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                int i = 0;
                int j = 0;


                String[] csv_lines = new String[dataGridView_CellStatistics.RowCount + 1];
                //String[] fldNames = new String[dataGridView_CellStatistics.Columns.Count];


                foreach (DataGridViewColumn column in dataGridView_CellStatistics.Columns)
                {
                    csv_lines[0] += column.HeaderText + ";";
                }
                csv_lines[0] += "Image Path";


                for (i = 0; i < dataGridView_CellStatistics.RowCount; i++)
                {
                    String row = "";
                    for (j = 0; j < dataGridView_CellStatistics.ColumnCount; j++)
                    {
                        DataGridViewCell cell = dataGridView_CellStatistics[j, i];
                        row += cell.Value + ";";
                    }
                    row += mainWindow.Image;
                    csv_lines[i + 1] = row;
                }


                File.WriteAllLines(saveFileDialogExcel.FileName, csv_lines);
            }
        }

        private void SaveDataToCSV(String fileName)
        {
            int i = 0;
            int j = 0;

            String[] csv_lines = new String[dataGridView_CellStatistics.RowCount];
            //String[] fldNames = new String[dataGridView_CellStatistics.Columns.Count];

            for (i = 0; i < dataGridView_CellStatistics.RowCount; i++)
            {
                String row = "";
                for (j = 0; j < dataGridView_CellStatistics.ColumnCount; j++)
                {
                    DataGridViewCell cell = dataGridView_CellStatistics[j, i];
                    row += cell.Value + ";";
                }
                row = row.Remove(row.Length - 1);
                csv_lines[i] = row;
            }
            File.WriteAllLines(fileName, csv_lines);
        }

        private void LoadDataFromCVS(String fileName)
        {
            String[] lines = File.ReadAllLines(fileName);
            dataGridView_CellStatistics.Rows.Clear();
            foreach (String line in lines)
            {
                String[] splittedValues = line.Split(';');
                dataGridView_CellStatistics.Rows.Add(splittedValues);
            }
        }

        private void checkBox_EditRGBSimultan_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox_EditRGBSimultan.Checked == true)
            {
                doubleSlider_ThreshRGB.Enabled = true;
                doubleSlider_ThreshR.Enabled = false;
                doubleSlider_ThreshG.Enabled = false;
                doubleSlider_ThreshB.Enabled = false;
            }
            else
            {
                doubleSlider_ThreshRGB.Enabled = false;
                doubleSlider_ThreshR.Enabled = true;
                doubleSlider_ThreshG.Enabled = true;
                doubleSlider_ThreshB.Enabled = true;
            }
        }

        private void doubleSlider_ThreshRGB_ValueChanged(object sender, EventArgs e)
        {
            if (checkBox_dynActualisation.Checked == true)
                B_Run_Click(sender, e);
        }

        private void toolStripButtonSaveAsImage_Click(object sender, EventArgs e)
        {
            if (saveFileDialogImage.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                mainWindow.SaveAsBitmap(saveFileDialogImage.FileName);
            }
        }

        private void dataGridView_CellStatistics_CurrentCellDirtyStateChanged(object sender, EventArgs e)
        {
            dataGridView_CellStatistics.EndEdit();
        }

        private void checkBox_IgnoreBorderCells_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox_IgnoreBorderCells.Checked == true)
            {
                singleSlider_MinCellAreaNoIgnoration.Enabled = true;
                singleSlider_BorderContactRatio.Enabled = true;
            }
            else
            {
                singleSlider_MinCellAreaNoIgnoration.Enabled = false;
                singleSlider_BorderContactRatio.Enabled = false;
            }
        }

        private void singleSlider_MaxContactArea_ValueChanged(object sender, EventArgs e)
        {
            if (checkBox_dynamicRefresh.Checked == true)
                B_Run_Click(sender, e);
        }

        private void singleSlider_MinContactCellArea_ValueChanged(object sender, EventArgs e)
        {
            if (checkBox_dynamicRefresh.Checked == true)
                B_Run_Click(sender, e);
        }

        private void checkBox_EditRGBHolesSimultan_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox_EditRGBHolesSimultan.Checked == true)
            {
                if (checkBox_FindCellHoles.Checked == true)
                {
                    doubleSlider_HolesThreshRGB.Enabled = true;
                    doubleSlider_HolesThreshR.Enabled = false;
                    doubleSlider_HolesThreshG.Enabled = false;
                    doubleSlider_HolesThreshB.Enabled = false;
                }
            }
            else
            {
                if (checkBox_FindCellHoles.Checked == true)
                {
                    doubleSlider_HolesThreshRGB.Enabled = false;
                    doubleSlider_HolesThreshR.Enabled = true;
                    doubleSlider_HolesThreshG.Enabled = true;
                    doubleSlider_HolesThreshB.Enabled = true;
                }
            }
        }

        private void saveProjectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (saveFileDialogProject.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                SaveProject(saveFileDialogProject.FileName);
            }
        }

        private void loadProjectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (openFileDialogProject.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                String[] lines = File.ReadAllLines(openFileDialogProject.FileName);
                foreach (String line in lines)
                {
                    String[] paramPair = line.Split(';');
                    switch (paramPair[0])
                    {
                        case "objects":
                            mainWindow.Load(paramPair[1]);
                            break;
                        case "parameters":
                            try
                            {
                                LoadParameters(paramPair[1]);
                            }
                            catch
                            {
                                inProcess = false;
                                bool status = checkBox_EditRGBSimultan.Checked;
                                checkBox_EditRGBSimultan.Checked = false;
                                checkBox_EditRGBSimultan.Checked = true;
                                checkBox_EditRGBSimultan.Checked = status;
                            }
                            break;
                        default:
                            break;
                    }
                }
                //Syncronisierung durchführen um aus den geladenen Polygonen die Zellstatistiken zu berechnen
                //Vorher DataGrid-Inhalt löschen falls vorhanden
                dataGridView_CellStatistics.Rows.Clear();

                toolStripButton_SyncHalObjWithGeoObj_Click(sender, e);
            }
        }
        private void doubleSlider_HolesThreshRGB_ValueChanged(object sender, EventArgs e)
        {
            if (checkBox_dynActualisation.Checked)
                B_Run_Click(sender, e);
        }

        private void btnLoad_Click(object sender, EventArgs e)
        {
            if (openFileDialogImageSet.ShowDialog() == System.Windows.Forms.DialogResult.OK && openFileDialogImageSet.FileNames.Length > 0)
            {
                //flowLayoutPanelImages.Controls.Clear(); //vorhandene Bilder löschen
                if (flowLayoutPanelImages.Controls.Count > 0)
                {
                    foreach (ImageControl.ImagePreviewBox box in flowLayoutPanelImages.Controls)
                    {
                        box.Selected = false;
                    }
                }
                foreach (var fileName in openFileDialogImageSet.FileNames)
                {
                    try
                    {
                        Bitmap img = new Bitmap(fileName);
                        ImageControl.ImagePreviewBox vBox = new ImageControl.ImagePreviewBox(img);
                        vBox.OnClick += new ImageControl.ImagePreviewBox.PictureBoxClickHandler(vBox_OnClick);
                        vBox.OnDeleting += new ImageControl.ImagePreviewBox.PictureBoxDeleteHandler(vBox_OnDeleting);
                        vBox.OnDeletingEverything += new EventHandler(vBox_OnDeletingEverything);
                        vBox.OnSelectAll += new EventHandler(vBox_OnSelectAll);
                        vBox.OnChangeSelectedParams += new EventHandler(vBox_OnChangeSelectedParams);
                        vBox.ImagePath = fileName;
                        vBox.Selected = true;
                        FileInfo file = new FileInfo(fileName);
                        vBox.Label = file.Name;
                        vBox.ParameterPath = Parameters.FileName;
                        flowLayoutPanelImages.Controls.Add(vBox);
                        Application.DoEvents();
                    }
                    catch
                    {
                        continue;
                    }
                }
            }
        }

        void vBox_OnChangeSelectedParams(object sender, EventArgs e)
        {
            if (openFileDialog2.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                foreach (ImageControl.ImagePreviewBox pBox in flowLayoutPanelImages.Controls.Cast<ImageControl.ImagePreviewBox>().Where(w => w.Selected == true))
                {
                    pBox.ParameterPath = openFileDialog2.FileName;
                }
            }
        }

        void vBox_OnSelectAll(object sender, EventArgs e)
        {
            foreach (ImageControl.ImagePreviewBox box in flowLayoutPanelImages.Controls)
            {
                box.Selected = true;
            }
        }
        void vBox_OnDeletingEverything(object sender, EventArgs e)
        {
            flowLayoutPanelImages.Controls.Clear();
        }

        void vBox_OnDeleting(object sender, EventArgs e)
        {
            var list = flowLayoutPanelImages.Controls.Cast<ImageControl.ImagePreviewBox>().Where(w => w.Selected == true).Select(s => s);
            for (int i = 0; i < flowLayoutPanelImages.Controls.Count; i++)
            {
                if ((flowLayoutPanelImages.Controls[i] as ImageControl.ImagePreviewBox).Selected == true)
                {
                    flowLayoutPanelImages.Controls.RemoveAt(i--);
                }
            }
        }

        void vBox_OnClick(object sender, ImageControl.ImageEventArgs e)
        {
            foreach (ImageControl.ImagePreviewBox control in flowLayoutPanelImages.Controls)
            {
                if (GetAsyncKeyState(Keys.ControlKey) == 0)
                {
                    control.Selected = false;
                }
                
            }

            Invalidate(true);

            (sender as ImageControl.ImagePreviewBox).Selected = true;

            try
            {
                LoadProject(tempProjectName[sender as ImageControl.ImagePreviewBox]);
                dataGridView_CellStatistics.Rows.Clear();

                toolStripButton_SyncHalObjWithGeoObj_Click(sender, e);
            }
            catch { }

        }

        public void LoadProject(string fileName)
        {
            String[] lines = File.ReadAllLines(fileName);
            foreach (String line in lines)
            {
                String[] paramPair = line.Split(';');
                switch (paramPair[0])
                {
                    case "objects":
                        mainWindow.Load(paramPair[1]);
                        //mainWindow.FitImgInPicBox();
                        break;
                    case "parameters":
                        try
                        {
                            LoadParameters(paramPair[1]);
                        }
                        catch
                        {
                            inProcess = false;
                            bool status = checkBox_EditRGBSimultan.Checked;
                            checkBox_EditRGBSimultan.Checked = false;
                            checkBox_EditRGBSimultan.Checked = true;
                            checkBox_EditRGBSimultan.Checked = status;
                        }
                        break;
                    default:
                        break;
                }
            }
        }

        public void SaveProject(String fileName)
        {

            FileInfo fi = new FileInfo(fileName);
            DirectoryInfo projectDir;
            if (fi.Exists)
            {
                projectDir = new DirectoryInfo(fi.DirectoryName);
            }
            else
            {
                //+ "\\" + (fi.Extension == String.Empty ? "" : fi.Name.Replace(fi.Extension, ""))
                projectDir = Directory.CreateDirectory(fi.DirectoryName);
            }

            DirectoryInfo paramDir = new DirectoryInfo(projectDir.FullName + "\\params");
            if (!paramDir.Exists)
            {
                paramDir.Create();
            }
            foreach (var key in cellDataPolyCollection.Keys)
            {
                cellDataPolyCollection[key].Status = (String)key.Cells["col_CellStatus"].Value;
                cellDataPolyCollection[key].Info = (String)key.Cells["col_Info"].Value;

            }
            mainWindow.Save(paramDir.FullName + "\\" + "objects");
            SaveParameters(paramDir.FullName + "\\" + "parameters");

            StreamWriter writer = File.CreateText(projectDir.FullName + "\\" + fi.Name);
            writer.WriteLine("objects;" + paramDir.FullName + "\\" + "objects");
            writer.WriteLine("parameters;" + paramDir.FullName + "\\" + "parameters");

            writer.Close();

        }

        private void btnRun_Click(object sender, EventArgs e)
        {
            int i = 0;

            Stopwatch timerMultiRun = new Stopwatch();
            timerMultiRun.Reset();
            timerMultiRun.Start();

            tempProjectName.Clear();
            try
            {
                if (Directory.Exists("tmp"))
                {
                    Directory.Delete("tmp", true);
                }

                foreach (Control c in flowLayoutPanelImages.Controls)
                {
                    if (breakLoop)
                    {
                        breakLoop = false;
                        break;
                    }
                    mainWindow.ImageBMP = (c as ImageControl.ImagePreviewBox).Image;

                    String imagePath = (c as ImageControl.ImagePreviewBox).ImagePath;
                    
                        if ((c as ImageControl.ImagePreviewBox).ParameterPath != String.Empty)
                        {
                            LoadParameters((c as ImageControl.ImagePreviewBox).ParameterPath);
                        }
                    mainWindow.Image = imagePath;
                    if (singleSlider_Area.Value == 0)
                        return;
                    if (inProcess == false)
                    {
                        try
                        {
                            this.Cursor = busyCursor;
                            inProcess = true;
                            HOperatorSet.ClearWindow(window);
                            HObject halImg;
                            HOperatorSet.ReadImage(out halImg, imagePath);
                            HOperatorSet.SetPart(window, 0, 0, -1, -1);
                            HOperatorSet.DispObj(halImg, window);
                            HOperatorSet.SetPart(window, 0, 0, -1, -1);
                            HOperatorSet.DispObj(halImg, window);
                            //Step-Statusbar initialisisieren
                            statusBar_Steps.Breakpoints.Clear();
                            cellDataPolyCollection.Clear();
                            dataGridView_CellStatistics.Rows.Clear();
                            statusBar_Steps.Value = 0;

                            switch (countcheckedBoxes())
                            {
                                case 1:
                                    if (checkBox_cellsegmentation.Checked == true)
                                    {
                                        BreakPoint ptn1 = new BreakPoint();
                                        ptn1.ProgressPosition = 1;
                                        ptn1.Radius = statusBar_Steps.Height / 4;
                                        statusBar_Steps.Add(ptn1);
                                    }
                                    statusBar_Steps.Invalidate();
                                    break;
                                case 2: if (checkBox_cellsegmentation.Checked == true)
                                    {
                                        BreakPoint ptn1 = new BreakPoint();
                                        ptn1.ProgressPosition = 0.47;
                                        ptn1.Radius = statusBar_Steps.Height / 4;
                                        statusBar_Steps.Add(ptn1);
                                    }
                                    if (checkBox_cellcoredetection.Checked == true)
                                    {
                                        BreakPoint ptn1 = new BreakPoint();
                                        ptn1.ProgressPosition = 1;
                                        ptn1.Radius = statusBar_Steps.Height / 4;
                                        statusBar_Steps.Add(ptn1);
                                    }
                                    statusBar_Steps.Invalidate();
                                    break;
                                case 3: if (checkBox_cellsegmentation.Checked == true)
                                    {
                                        BreakPoint ptn1 = new BreakPoint();
                                        ptn1.ProgressPosition = 0.33;
                                        ptn1.Radius = 15;
                                        statusBar_Steps.Add(ptn1);
                                    }
                                    if (checkBox_cellcoredetection.Checked == true)
                                    {
                                        BreakPoint ptn1 = new BreakPoint();
                                        ptn1.ProgressPosition = 0.66;
                                        //ptn1.Radius =statusBar_Steps.Height / 4;
                                        ptn1.Radius = 15;
                                        statusBar_Steps.Add(ptn1);
                                    }
                                    if ((checkBox_cellclustersplittingA.Checked == true) || (checkBox_cellclustersplittingB.Checked == true))
                                    {
                                        BreakPoint ptn1 = new BreakPoint();
                                        ptn1.Radius = 15;
                                        ptn1.ProgressPosition = 1 - ((double)ptn1.Radius / statusBar_Steps.Width);
                                        statusBar_Steps.Add(ptn1);
                                    }
                                    statusBar_Steps.Invalidate();
                                    break;
                            }
                            if ((imagePath != null) && (imagePath != "") && (checkBox_cellsegmentation.Checked == true))
                            {
                                //Zuerst mögliche GeoObjekte von einer vorherigen Ausführung löschen
                                mainWindow.GeoObjects.Clear();
                                //Neu generierte Zellen durch den Zelltrennungsalgo wieder löschen
                                newCellList.Clear();
                                cells.Clear();
                                mainWindow.Refresh();

                                //ParameterizedThreadStart pts = new ParameterizedThreadStart(runAlgo);
                                //thread = new Thread(pts);

                                Object[] pars = new Object[32];
                                pars[0] = comboBox_SegmantationMethod.Text;
                                pars[1] = Convert.ToInt32(comboBox_DCP_Levels.Text);
                                pars[2] = doubleSlider_PK_ThreshBackgroundSeg.LowerValue;
                                pars[3] = doubleSlider_PK_ThreshBackgroundSeg.UpperValue;
                                pars[4] = singleSlider_PK_maxCellArea.Value;
                                pars[5] = singleSlider_PK_MaxFillHoleArea.Value;
                                pars[6] = textBox_BinsCells.Text;
                                pars[7] = textBox_CellContourPointsReduction.Text;
                                pars[8] = textBox_CoreContourPointsReduction.Text;
                                pars[9] = singleSlider_MinCoreArea.Value;
                                pars[10] = checkBox_showCellNumber.Checked;
                                pars[11] = checkBox_DeleteSatRegions.Checked;
                                pars[12] = floatSingleSlider_SatDeviationFactor.Value;
                                pars[13] = singleSlider_MinCellAreaNoIgnoration.Value;
                                pars[14] = singleSlider_BorderContactRatio.Value;
                                pars[15] = checkBox_contextBasedSeparation.Checked;
                                pars[16] = checkBox_cellclustersplittingB.Checked;
                                pars[17] = singleSlider_minArea_cellGrowthSimulation.Value;
                                pars[18] = checkBox_barbellCellDivision.Checked;
                                pars[19] = checkBox_ImagePreProcessing.Checked;
                                pars[20] = floatSingleSlider_PreprocessingColorRatio.Value;
                                pars[21] = comboBox_Color.SelectedValue;
                                pars[22] = singleSlider_MaxBarbellCellSize.Value;
                                pars[23] = comboBox_feature1.Text;
                                pars[24] = comboBox_feature2.Text;
                                pars[25] = comboBox_feature3.Text;
                                pars[26] = textBox_feature1_min.Text;
                                pars[27] = textBox_feature1_max.Text;
                                pars[28] = textBox_feature2_min.Text;
                                pars[29] = textBox_feature2_max.Text;
                                pars[30] = textBox_feature3_min.Text;
                                pars[31] = textBox_feature3_max.Text;

                                Application.DoEvents();

                                //thread.Start(pars);
                                //thread.BeginInvoke(

                                //thread.Join();
                                //WaitCallback waitCallback = new WaitCallback(runAlgo);
                                thread = new Thread(new ParameterizedThreadStart(runAlgo));
                                thread.Start(pars);

                                //threadPool.Add(t);
                                //t.Start(pars);

                                //ThreadPool.QueueUserWorkItem(waitCallback, pars);

                                //WaitHandle.WaitAll(new WaitHandle[] { (WaitHandle)waitCallback. }, -1);
                                while (inProcess)
                                {
                                    Thread.Sleep(100);
                                    Application.DoEvents();
                                }
                                String tmpProjectFile = "tmp\\project" + i.ToString() + "\\p" + i.ToString() + ".pro";
                                tempProjectName.Add(c as ImageControl.ImagePreviewBox, tmpProjectFile);
                                SaveProject(tmpProjectFile);
                                i++;
                                //Daten in Control speichern um die Anzeige der durchschnittlichen Statistik aller markierten
                                //Controls zu ermöglichen
                                (c as ImageControl.ImagePreviewBox).Analysed = true;
                                (c as ImageControl.ImagePreviewBox).TotalCellCount = Convert.ToInt32(textBox_TotalCellCount.Text);
                                (c as ImageControl.ImagePreviewBox).AliveCellCount = Convert.ToInt32(textBox_CellsAlive.Text);
                                (c as ImageControl.ImagePreviewBox).CellDensity = Convert.ToDouble(textBox_CellDensity.Text);
                                (c as ImageControl.ImagePreviewBox).CellDensityUnit = textBox_CellDensityUnit.Text;
                                (c as ImageControl.ImagePreviewBox).AverageCellArea = Convert.ToDouble(textBox_AverageCellArea.Text);
                                (c as ImageControl.ImagePreviewBox).AverageCellAreaUnit = textBox_AverageCellAreaUnit.Text;
                            }
                        }
                        catch
                        {
                            inProcess = false;
                            Cursor = Cursors.Default;
                        }
                    }
                }
                //Anzeige der gemittelten Statistiken 
                int counter = 0;
                int overallTotalCellCount = 0;
                int overallTotalAliveCount = 0;
                int overallTotalDeadCount = 0;
                double overallMeanCellDensity = 0;
                string overallMeanCellDensityUnit = "";
                double overallMeanAverageCellArea = 0;
                string overallMeanAverageCellAreaUnit = "";
                foreach (Control c in flowLayoutPanelImages.Controls)
                {
                    if ((c as ImageControl.ImagePreviewBox).Analysed == true)
                    {
                        counter++;
                        overallTotalCellCount = overallTotalCellCount + (c as ImageControl.ImagePreviewBox).TotalCellCount;
                        overallTotalAliveCount = overallTotalAliveCount + (c as ImageControl.ImagePreviewBox).AliveCellCount;
                        overallTotalDeadCount = overallTotalDeadCount + ((c as ImageControl.ImagePreviewBox).TotalCellCount - (c as ImageControl.ImagePreviewBox).AliveCellCount);

                        switch ((c as ImageControl.ImagePreviewBox).CellDensityUnit)
                        {
                            case " Cells / m²": overallMeanCellDensity = overallMeanCellDensity + (c as ImageControl.ImagePreviewBox).CellDensity;
                                break;
                            case " Cells / cm²": overallMeanCellDensity = overallMeanCellDensity + ((c as ImageControl.ImagePreviewBox).CellDensity * Math.Pow(100, 2));
                                break;
                            case " Cells / mm²": overallMeanCellDensity = overallMeanCellDensity + ((c as ImageControl.ImagePreviewBox).CellDensity * Math.Pow(1000, 2));
                                break;
                            case " Cells / ym²": overallMeanCellDensity = overallMeanCellDensity + ((c as ImageControl.ImagePreviewBox).CellDensity * Math.Pow(1000000, 2));
                                break;
                            case " Cells / nm²": overallMeanCellDensity = overallMeanCellDensity + ((c as ImageControl.ImagePreviewBox).CellDensity * Math.Pow(1000000000, 2));
                                break;
                            case " Cells / pm²": overallMeanCellDensity = overallMeanCellDensity + ((c as ImageControl.ImagePreviewBox).CellDensity * Math.Pow(1000000000000, 2));
                                break;
                        }
                        switch ((c as ImageControl.ImagePreviewBox).AverageCellAreaUnit)
                        {
                            case " m²": overallMeanAverageCellArea = overallMeanAverageCellArea + (c as ImageControl.ImagePreviewBox).AverageCellArea;
                                break;
                            case " cm²": overallMeanAverageCellArea = overallMeanAverageCellArea + ((c as ImageControl.ImagePreviewBox).AverageCellArea * Math.Pow(100, 2));
                                break;
                            case " mm²": overallMeanAverageCellArea = overallMeanAverageCellArea + ((c as ImageControl.ImagePreviewBox).AverageCellArea * Math.Pow(1000, 2));
                                break;
                            case " ym²": overallMeanAverageCellArea = overallMeanAverageCellArea + ((c as ImageControl.ImagePreviewBox).AverageCellArea * Math.Pow(1000000, 2));
                                break;
                            case " nm²": overallMeanAverageCellArea = overallMeanAverageCellArea + ((c as ImageControl.ImagePreviewBox).AverageCellArea * Math.Pow(1000000000, 2));
                                break;
                            case " pm²": overallMeanAverageCellArea = overallMeanAverageCellArea + ((c as ImageControl.ImagePreviewBox).AverageCellArea * Math.Pow(1000000000000, 2));
                                break;
                        }
                    }
                }
                textBox_OverallTotalCellCount.Text = Convert.ToString(overallTotalCellCount);
                textBox_OverallAliveCellCount.Text = Convert.ToString(overallTotalAliveCount);
                textBox_OverallDeadCellCount.Text = Convert.ToString(overallTotalDeadCount);
                textBox_MeanViability.Text = Convert.ToString(Math.Round(((double)overallTotalAliveCount / overallTotalCellCount) * 100, 2)) + " %";

                overallMeanAverageCellArea = overallMeanAverageCellArea / counter;
                overallMeanCellDensity = overallMeanCellDensity / counter;

                int unitCounter = 0;
                double org_overallMeanAverageCellArea = overallMeanAverageCellArea;

                if ((overallMeanAverageCellArea >= 10000) && (overallMeanAverageCellArea <= 100000))
                {
                    overallMeanAverageCellArea = overallMeanAverageCellArea / 10000;
                    overallMeanAverageCellAreaUnit = " cm²";
                }
                else if (overallMeanAverageCellArea > 100000)
                {
                    while (overallMeanAverageCellArea > 100000)
                    {
                        overallMeanAverageCellArea = overallMeanAverageCellArea / 1000000;
                        unitCounter++;
                    }
                    switch (unitCounter)
                    {
                        case 1: overallMeanAverageCellAreaUnit = " mm²";
                            break;
                        case 2: overallMeanAverageCellAreaUnit = " ym²";
                            break;
                        case 3: overallMeanAverageCellAreaUnit = " nm²";
                            break;
                        case 4: overallMeanAverageCellAreaUnit = " pm²";
                            break;
                    }
                }
                else
                {
                    overallMeanAverageCellAreaUnit = " m²";
                }


                double org_overallMeanCellDensity = overallMeanCellDensity;

                if ((overallMeanCellDensity >= 10000) && (overallMeanCellDensity <= 100000))
                {
                    overallMeanCellDensity = overallMeanCellDensity / 10000;
                    overallMeanCellDensityUnit = " Cells / cm²";
                }
                else if (overallMeanCellDensity > 100000)
                {
                    while (overallMeanCellDensity > 100000)
                    {
                        overallMeanCellDensity = overallMeanCellDensity / 1000000;
                        unitCounter++;
                    }
                    switch (unitCounter)
                    {
                        case 1: overallMeanCellDensityUnit = " Cells / mm²";
                            break;
                        case 2: overallMeanCellDensityUnit = " Cells / ym²";
                            break;
                        case 3: overallMeanCellDensityUnit = " Cells / nm²";
                            break;
                        case 4: overallMeanCellDensityUnit = " Cells / pm²";
                            break;
                    }
                }
                else
                {
                    overallMeanCellDensityUnit = " Cells / m²";
                }

                textBox_OverallCellDensity.Text = Convert.ToString(Math.Round(overallMeanCellDensity, 1));
                textBox_OverallCellDensityUnit.Text = overallMeanCellDensityUnit;
                textBox_OverallAvgCellArea.Text = Convert.ToString(Math.Round(overallMeanAverageCellArea, 1));
                textBox_OverallAvgCellAreaUnit.Text = overallMeanAverageCellAreaUnit;
                breakLoop = false;
                threadPool.Clear();
                timerMultiRun.Stop();
                TimeToTextboxStapel(timerMultiRun);
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void saveProjectMapToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialogSaveProjectMap.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                DirectoryInfo tmpDir;
                try
                {
                    tmpDir = new DirectoryInfo("tmp");
                }
                catch (DirectoryNotFoundException)
                {
                    MessageBox.Show("Nothing to save");
                    return;
                }
                foreach (var subDir in tmpDir.GetDirectories())
                {
                    CopyDirectoryWithIncludedFiles(subDir.FullName, folderBrowserDialogSaveProjectMap.SelectedPath);
                }
            }
        }

        private void CopyDirectoryWithIncludedFiles(string dirCopySource, string dirCopyTarget)
        {
            // alle Unterverzeichnisse des aktuellen Verzeichnisses ermitteln
            string[] subDirectories = Directory.GetDirectories(dirCopySource);

            // Zielpfad erzeugen
            StringBuilder newTargetPath = new StringBuilder();
            {
                newTargetPath.Append(dirCopyTarget);
                newTargetPath.Append(dirCopySource.Substring(dirCopySource.LastIndexOf(@"\")));
            }
            // wenn aktueller Ordner nicht existiert -> ersstellen
            if (!Directory.Exists(newTargetPath.ToString()))
                Directory.CreateDirectory(newTargetPath.ToString());

            // Unterverzeichnise durchlaufen und Funktion mit dazu gehörigen Zielpfad erneut aufrufen (Rekursion)
            foreach (string subDirectory in subDirectories)
            {
                string newDirectoryPath = subDirectory;

                // wenn ''/'' an letzter Stelle dann entfernen
                if (newDirectoryPath.LastIndexOf(@"\") == (newDirectoryPath.Length - 1))
                    newDirectoryPath = newDirectoryPath.Substring(0, newDirectoryPath.Length - 1);

                // rekursiever Aufruf
                CopyDirectoryWithIncludedFiles(newDirectoryPath, newTargetPath.ToString());
            }

            // alle enthaltenden Dateien des aktuellen Verzeichnisses ermitteln
            string[] fileNames = Directory.GetFiles(dirCopySource);
            foreach (string fileSource in fileNames)
            {
                // Zielpfad + Dateiname
                StringBuilder fileTarget = new StringBuilder();
                {
                    fileTarget.Append(newTargetPath);
                    fileTarget.Append(fileSource.Substring(fileSource.LastIndexOf(@"\")));
                }

                // Datei kopieren, wenn schon vorhanden überschreiben
                File.Copy(fileSource, fileTarget.ToString(), true);
            }
        }

        private void loadProjectMapToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialogSaveProjectMap.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                tempProjectName.Clear();
                DirSearch(folderBrowserDialogSaveProjectMap.SelectedPath, ".pro");
                tabControl_Parameter.SelectedTab = tabPageMultiImageAnalysis;
            }
        }

        void DirSearch(string sDir, string searchPattern)
        {
            try
            {
                foreach (string d in Directory.GetDirectories(sDir))
                {
                    foreach (string f in Directory.GetFiles(d))
                    {
                        FileInfo fi = new FileInfo(f);
                        if (fi.Extension != searchPattern)
                        {
                            continue;
                        }

                        LoadProject(f);

                        Bitmap img = new Bitmap(mainWindow.Image);
                        ImageControl.ImagePreviewBox vBox = new ImageControl.ImagePreviewBox(img);
                        vBox.OnClick += new ImageControl.ImagePreviewBox.PictureBoxClickHandler(vBox_OnClick);
                        vBox.OnDeleting += new ImageControl.ImagePreviewBox.PictureBoxDeleteHandler(vBox_OnDeleting);
                        vBox.OnDeletingEverything += new EventHandler(vBox_OnDeletingEverything);
                        vBox.ImagePath = f;
                        FileInfo file = new FileInfo(f);
                        vBox.Label = file.Name;
                        tempProjectName.Add(vBox, fi.FullName);
                        flowLayoutPanelImages.Controls.Add(vBox);
                    }

                    DirSearch(d, searchPattern);
                }
            }

            catch (System.Exception excpt)
            {
                Console.WriteLine(excpt.Message);
            }
        }

        private void checkBox_cellclustersplittingB_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox_cellclustersplittingB.Checked == true)
            {
                singleSlider_minArea_cellGrowthSimulation.Enabled = true;
                checkBox_cellsegmentation.Checked = true;
                checkBox_cellcoredetection.Checked = true;
                checkBox_cellclustersplittingA.Checked = false;
            }
            else
            {
                singleSlider_minArea_cellGrowthSimulation.Enabled = false;
            }
        }

        private void checkBox_cellclustersplittingA_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox_cellclustersplittingA.Checked == true)
            {
                checkBox_cellsegmentation.Checked = true;
                checkBox_cellcoredetection.Checked = true;
                checkBox_cellclustersplittingB.Checked = false;
            }
        }

        private void checkBox_cellcoredetection_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox_cellcoredetection.Checked == true)
                checkBox_cellsegmentation.Checked = true;
        }

        private void checkBox_contextBasedSeparation_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox_contextBasedSeparation.Checked == true)
                checkBox_cellsegmentation.Checked = true;
        }

        private void saveCurrentImageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (saveFileDialogCurrentImage.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                Bitmap bmp = new Bitmap(mainWindow.Image);
                Graphics g = Graphics.FromImage(bmp);
                foreach (var point in mainWindow.manualCellCountPoints)
                {
                    g.FillEllipse(new SolidBrush(mainWindow.complementColorToolStripMenuItem.Checked ? point.color : mainWindow.countColor), new Rectangle(point.point.X - (mainWindow.TrackBarRadius / 2), point.point.Y - (mainWindow.TrackBarRadius / 2), mainWindow.TrackBarRadius, mainWindow.TrackBarRadius));
                }
                g.DrawString(mainWindow.manualCellCountPoints.Count.ToString(), new Font("Arial", 17), Brushes.Red, 0, 0);
                bmp.Save(saveFileDialogCurrentImage.FileName);
            }
        }
        private void dataGridView_CellStatistics_Resize(object sender, EventArgs e)
        {
            if (dataGridView_CellStatistics.SelectedCells.Count > 0)
            {
                dataGridView_CellStatistics.FirstDisplayedCell = dataGridView_CellStatistics.SelectedCells[0];
            }
        }

        private void mainWindow_Load(object sender, EventArgs e)
        {

        }
    }
}
